Remove protocol fees from RFQ orders (#45)
* `@0x/contracts-zero-ex`: Remove protocol fees from native orders in certain scenarios. * `@0x/contracts-zero-ex`: update changelog * `@0x/contracts-zero-ex`: Add `taker` field to RFQ orders.` `@0x/contracts-zero-ex`: Introduce protocol fees to all limit orders again. * `@0x/contracts-zero-ex`: Rebase. Co-authored-by: Lawrence Forman <me@merklejerk.com>
This commit is contained in:
		@@ -37,6 +37,10 @@
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Do not try to pull all tokens if selling all ETH in `TransformERC20Feature`",
 | 
			
		||||
                "pr": 46
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Remove protocol fees from all RFQ orders and add `taker` field to RFQ orders",
 | 
			
		||||
                "pr": 45
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,6 @@ interface INativeOrdersFeature {
 | 
			
		||||
    /// @param taker The taker of the order.
 | 
			
		||||
    /// @param takerTokenFilledAmount How much taker token was filled.
 | 
			
		||||
    /// @param makerTokenFilledAmount How much maker token was filled.
 | 
			
		||||
    /// @param protocolFeePaid How much protocol fee was paid.
 | 
			
		||||
    /// @param pool The fee pool associated with this order.
 | 
			
		||||
    event RfqOrderFilled(
 | 
			
		||||
        bytes32 orderHash,
 | 
			
		||||
@@ -66,7 +65,6 @@ interface INativeOrdersFeature {
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        uint128 takerTokenFilledAmount,
 | 
			
		||||
        uint128 makerTokenFilledAmount,
 | 
			
		||||
        uint256 protocolFeePaid,
 | 
			
		||||
        bytes32 pool
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@@ -126,8 +124,7 @@ interface INativeOrdersFeature {
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
 | 
			
		||||
 | 
			
		||||
    /// @dev Fill an RFQ order for up to `takerTokenFillAmount` taker tokens.
 | 
			
		||||
    ///      The taker will be the caller. ETH should be attached to pay the
 | 
			
		||||
    ///      protocol fee.
 | 
			
		||||
    ///      The taker will be the caller.
 | 
			
		||||
    /// @param order The RFQ order.
 | 
			
		||||
    /// @param signature The order signature.
 | 
			
		||||
    /// @param takerTokenFillAmount Maximum taker token amount to fill this order with.
 | 
			
		||||
@@ -139,7 +136,6 @@ interface INativeOrdersFeature {
 | 
			
		||||
        uint128 takerTokenFillAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
 | 
			
		||||
 | 
			
		||||
    /// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
 | 
			
		||||
@@ -160,9 +156,7 @@ interface INativeOrdersFeature {
 | 
			
		||||
        returns (uint128 makerTokenFilledAmount);
 | 
			
		||||
 | 
			
		||||
    /// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
 | 
			
		||||
    ///      The taker will be the caller. ETH protocol fees can be
 | 
			
		||||
    ///      attached to this call. Any unspent ETH will be refunded to
 | 
			
		||||
    ///      the caller.
 | 
			
		||||
    ///      The taker will be the caller.
 | 
			
		||||
    /// @param order The RFQ order.
 | 
			
		||||
    /// @param signature The order signature.
 | 
			
		||||
    /// @param takerTokenFillAmount How much taker token to fill this order with.
 | 
			
		||||
@@ -173,7 +167,6 @@ interface INativeOrdersFeature {
 | 
			
		||||
        uint128 takerTokenFillAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 makerTokenFilledAmount);
 | 
			
		||||
 | 
			
		||||
    /// @dev Fill a limit order. Internal variant. ETH protocol fees can be
 | 
			
		||||
@@ -197,9 +190,7 @@ interface INativeOrdersFeature {
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
 | 
			
		||||
 | 
			
		||||
    /// @dev Fill an RFQ order. Internal variant. ETH protocol fees can be
 | 
			
		||||
    ///      attached to this call. Any unspent ETH will be refunded to
 | 
			
		||||
    ///      `msg.sender` (not `sender`).
 | 
			
		||||
    /// @dev Fill an RFQ order. Internal variant.
 | 
			
		||||
    /// @param order The RFQ order.
 | 
			
		||||
    /// @param signature The order signature.
 | 
			
		||||
    /// @param takerTokenFillAmount Maximum taker token to fill this order with.
 | 
			
		||||
@@ -213,7 +204,6 @@ interface INativeOrdersFeature {
 | 
			
		||||
        address taker
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
 | 
			
		||||
 | 
			
		||||
    /// @dev Cancel a single limit order. The caller must be the maker.
 | 
			
		||||
 
 | 
			
		||||
@@ -210,7 +210,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        override
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
 | 
			
		||||
    {
 | 
			
		||||
        FillNativeOrderResults memory results =
 | 
			
		||||
@@ -220,7 +219,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
                takerTokenFillAmount,
 | 
			
		||||
                msg.sender
 | 
			
		||||
            );
 | 
			
		||||
        _refundExcessProtocolFeeToSender(results.ethProtocolFeePaid);
 | 
			
		||||
        (takerTokenFilledAmount, makerTokenFilledAmount) = (
 | 
			
		||||
            results.takerTokenFilledAmount,
 | 
			
		||||
            results.makerTokenFilledAmount
 | 
			
		||||
@@ -280,7 +278,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        override
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 makerTokenFilledAmount)
 | 
			
		||||
    {
 | 
			
		||||
        FillNativeOrderResults memory results =
 | 
			
		||||
@@ -298,7 +295,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
                takerTokenFillAmount
 | 
			
		||||
            ).rrevert();
 | 
			
		||||
        }
 | 
			
		||||
        _refundExcessProtocolFeeToSender(results.ethProtocolFeePaid);
 | 
			
		||||
        makerTokenFilledAmount = results.makerTokenFilledAmount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -359,7 +355,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
        public
 | 
			
		||||
        virtual
 | 
			
		||||
        override
 | 
			
		||||
        payable
 | 
			
		||||
        onlySelf
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
 | 
			
		||||
    {
 | 
			
		||||
@@ -370,7 +365,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
                takerTokenFillAmount,
 | 
			
		||||
                taker
 | 
			
		||||
            );
 | 
			
		||||
        _refundExcessProtocolFeeToSender(results.ethProtocolFeePaid);
 | 
			
		||||
        (takerTokenFilledAmount, makerTokenFilledAmount) = (
 | 
			
		||||
            results.takerTokenFilledAmount,
 | 
			
		||||
            results.makerTokenFilledAmount
 | 
			
		||||
@@ -898,6 +892,15 @@ contract NativeOrdersFeature is
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Must be fillable by the taker.
 | 
			
		||||
        if (order.taker != address(0) && order.taker != taker) {
 | 
			
		||||
            LibNativeOrdersRichErrors.OrderNotFillableByTakerError(
 | 
			
		||||
                orderInfo.orderHash,
 | 
			
		||||
                taker,
 | 
			
		||||
                order.taker
 | 
			
		||||
            ).rrevert();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Signature must be valid for the order.
 | 
			
		||||
        {
 | 
			
		||||
            address signer = LibSignature.getSignerOfHash(orderInfo.orderHash, signature);
 | 
			
		||||
@@ -910,9 +913,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Pay the protocol fee.
 | 
			
		||||
        results.ethProtocolFeePaid = _collectProtocolFee(order.pool);
 | 
			
		||||
 | 
			
		||||
        // Settle between the maker and taker.
 | 
			
		||||
        (results.takerTokenFilledAmount, results.makerTokenFilledAmount) = _settleOrder(
 | 
			
		||||
            SettleOrderInfo({
 | 
			
		||||
@@ -936,7 +936,6 @@ contract NativeOrdersFeature is
 | 
			
		||||
            address(order.takerToken),
 | 
			
		||||
            results.takerTokenFilledAmount,
 | 
			
		||||
            results.makerTokenFilledAmount,
 | 
			
		||||
            results.ethProtocolFeePaid,
 | 
			
		||||
            order.pool
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@ library LibNativeOrder {
 | 
			
		||||
        uint128 makerAmount;
 | 
			
		||||
        uint128 takerAmount;
 | 
			
		||||
        address maker;
 | 
			
		||||
        address taker;
 | 
			
		||||
        address txOrigin;
 | 
			
		||||
        bytes32 pool;
 | 
			
		||||
        uint64 expiry;
 | 
			
		||||
@@ -102,13 +103,14 @@ library LibNativeOrder {
 | 
			
		||||
    //       "uint128 takerAmount,",
 | 
			
		||||
    //       "address maker,",
 | 
			
		||||
    //       "address txOrigin,",
 | 
			
		||||
    //       "address taker,",
 | 
			
		||||
    //       "bytes32 pool,",
 | 
			
		||||
    //       "uint64 expiry,",
 | 
			
		||||
    //       "uint256 salt"
 | 
			
		||||
    //     ")"
 | 
			
		||||
    // ))
 | 
			
		||||
    uint256 private constant _RFQ_ORDER_TYPEHASH =
 | 
			
		||||
        0xc6b3034376598bc7f28b05e81db7ed88486dcdb6b4a6c7300353fffc5f31f382;
 | 
			
		||||
        0xe593d3fdfa8b60e5e17a1b2204662ecbe15c23f2084b9ad5bae40359540a7da9;
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the struct hash of a limit order.
 | 
			
		||||
    /// @param order The limit order.
 | 
			
		||||
@@ -181,6 +183,7 @@ library LibNativeOrder {
 | 
			
		||||
        //   order.makerAmount,
 | 
			
		||||
        //   order.takerAmount,
 | 
			
		||||
        //   order.maker,
 | 
			
		||||
        //   order.taker,
 | 
			
		||||
        //   order.txOrigin,
 | 
			
		||||
        //   order.pool,
 | 
			
		||||
        //   order.expiry,
 | 
			
		||||
@@ -199,15 +202,17 @@ library LibNativeOrder {
 | 
			
		||||
            mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
 | 
			
		||||
            // order.maker;
 | 
			
		||||
            mstore(add(mem, 0xA0), and(ADDRESS_MASK, mload(add(order, 0x80))))
 | 
			
		||||
            // order.txOrigin;
 | 
			
		||||
            // order.taker;
 | 
			
		||||
            mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
 | 
			
		||||
            // order.txOrigin;
 | 
			
		||||
            mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
 | 
			
		||||
            // order.pool;
 | 
			
		||||
            mstore(add(mem, 0xE0), mload(add(order, 0xC0)))
 | 
			
		||||
            mstore(add(mem, 0x100), mload(add(order, 0xE0)))
 | 
			
		||||
            // order.expiry;
 | 
			
		||||
            mstore(add(mem, 0x100), and(UINT_64_MASK, mload(add(order, 0xE0))))
 | 
			
		||||
            mstore(add(mem, 0x120), and(UINT_64_MASK, mload(add(order, 0x100))))
 | 
			
		||||
            // order.salt;
 | 
			
		||||
            mstore(add(mem, 0x120), mload(add(order, 0x100)))
 | 
			
		||||
            structHash := keccak256(mem, 0x140)
 | 
			
		||||
            mstore(add(mem, 0x140), mload(add(order, 0x120)))
 | 
			
		||||
            structHash := keccak256(mem, 0x160)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,6 @@ contract TestMetaTransactionsNativeOrdersFeature is
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        override
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
 | 
			
		||||
    {
 | 
			
		||||
        emit FillRfqOrderCalled(
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ const COMMON_ORDER_DEFAULT_VALUES = {
 | 
			
		||||
    makerAmount: ZERO,
 | 
			
		||||
    takerAmount: ZERO,
 | 
			
		||||
    maker: NULL_ADDRESS,
 | 
			
		||||
    taker: NULL_ADDRESS,
 | 
			
		||||
    pool: hexUtils.leftPad(0),
 | 
			
		||||
    expiry: ZERO,
 | 
			
		||||
    salt: ZERO,
 | 
			
		||||
@@ -29,7 +30,6 @@ const COMMON_ORDER_DEFAULT_VALUES = {
 | 
			
		||||
const LIMIT_ORDER_DEFAULT_VALUES = {
 | 
			
		||||
    ...COMMON_ORDER_DEFAULT_VALUES,
 | 
			
		||||
    takerTokenFeeAmount: ZERO,
 | 
			
		||||
    taker: NULL_ADDRESS,
 | 
			
		||||
    sender: NULL_ADDRESS,
 | 
			
		||||
    feeRecipient: NULL_ADDRESS,
 | 
			
		||||
};
 | 
			
		||||
@@ -63,6 +63,7 @@ export abstract class OrderBase {
 | 
			
		||||
    public takerAmount: BigNumber;
 | 
			
		||||
    public maker: string;
 | 
			
		||||
    public pool: string;
 | 
			
		||||
    public taker: string;
 | 
			
		||||
    public expiry: BigNumber;
 | 
			
		||||
    public salt: BigNumber;
 | 
			
		||||
    public chainId: number;
 | 
			
		||||
@@ -75,6 +76,7 @@ export abstract class OrderBase {
 | 
			
		||||
        this.makerAmount = _fields.makerAmount;
 | 
			
		||||
        this.takerAmount = _fields.takerAmount;
 | 
			
		||||
        this.maker = _fields.maker;
 | 
			
		||||
        this.taker = _fields.taker;
 | 
			
		||||
        this.pool = _fields.pool;
 | 
			
		||||
        this.expiry = _fields.expiry;
 | 
			
		||||
        this.salt = _fields.salt;
 | 
			
		||||
@@ -142,7 +144,6 @@ export class LimitOrder extends OrderBase {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    public takerTokenFeeAmount: BigNumber;
 | 
			
		||||
    public taker: string;
 | 
			
		||||
    public sender: string;
 | 
			
		||||
    public feeRecipient: string;
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +151,6 @@ export class LimitOrder extends OrderBase {
 | 
			
		||||
        const _fields = { ...LIMIT_ORDER_DEFAULT_VALUES, ...fields };
 | 
			
		||||
        super(_fields);
 | 
			
		||||
        this.takerTokenFeeAmount = _fields.takerTokenFeeAmount;
 | 
			
		||||
        this.taker = _fields.taker;
 | 
			
		||||
        this.sender = _fields.sender;
 | 
			
		||||
        this.feeRecipient = _fields.feeRecipient;
 | 
			
		||||
    }
 | 
			
		||||
@@ -246,6 +246,7 @@ export class RfqOrder extends OrderBase {
 | 
			
		||||
                        'uint128 makerAmount',
 | 
			
		||||
                        'uint128 takerAmount',
 | 
			
		||||
                        'address maker',
 | 
			
		||||
                        'address taker',
 | 
			
		||||
                        'address txOrigin',
 | 
			
		||||
                        'bytes32 pool',
 | 
			
		||||
                        'uint64 expiry',
 | 
			
		||||
@@ -272,6 +273,7 @@ export class RfqOrder extends OrderBase {
 | 
			
		||||
            makerAmount: this.makerAmount,
 | 
			
		||||
            takerAmount: this.takerAmount,
 | 
			
		||||
            maker: this.maker,
 | 
			
		||||
            taker: this.taker,
 | 
			
		||||
            txOrigin: this.txOrigin,
 | 
			
		||||
            pool: this.pool,
 | 
			
		||||
            expiry: this.expiry,
 | 
			
		||||
@@ -291,6 +293,7 @@ export class RfqOrder extends OrderBase {
 | 
			
		||||
                hexUtils.leftPad(this.makerAmount),
 | 
			
		||||
                hexUtils.leftPad(this.takerAmount),
 | 
			
		||||
                hexUtils.leftPad(this.maker),
 | 
			
		||||
                hexUtils.leftPad(this.taker),
 | 
			
		||||
                hexUtils.leftPad(this.txOrigin),
 | 
			
		||||
                hexUtils.leftPad(this.pool),
 | 
			
		||||
                hexUtils.leftPad(this.expiry),
 | 
			
		||||
@@ -309,6 +312,7 @@ export class RfqOrder extends OrderBase {
 | 
			
		||||
                    { type: 'uint128', name: 'makerAmount' },
 | 
			
		||||
                    { type: 'uint128', name: 'takerAmount' },
 | 
			
		||||
                    { type: 'address', name: 'maker' },
 | 
			
		||||
                    { type: 'address', name: 'taker' },
 | 
			
		||||
                    { type: 'address', name: 'txOrigin' },
 | 
			
		||||
                    { type: 'bytes32', name: 'pool' },
 | 
			
		||||
                    { type: 'uint64', name: 'expiry' },
 | 
			
		||||
@@ -323,6 +327,7 @@ export class RfqOrder extends OrderBase {
 | 
			
		||||
                makerAmount: this.makerAmount.toString(10),
 | 
			
		||||
                takerAmount: this.takerAmount.toString(10),
 | 
			
		||||
                maker: this.maker,
 | 
			
		||||
                taker: this.taker,
 | 
			
		||||
                txOrigin: this.txOrigin,
 | 
			
		||||
                pool: this.pool,
 | 
			
		||||
                expiry: this.expiry.toString(10),
 | 
			
		||||
 
 | 
			
		||||
@@ -197,11 +197,12 @@ blockchainTests.resets('MetaTransactions feature', env => {
 | 
			
		||||
            const fillAmount = new BigNumber(23456);
 | 
			
		||||
            const mtx = getRandomMetaTransaction({
 | 
			
		||||
                callData: nativeOrdersFeature.fillRfqOrder(order, sig, fillAmount).getABIEncodedTransactionData(),
 | 
			
		||||
                value: ZERO_AMOUNT,
 | 
			
		||||
            });
 | 
			
		||||
            const signature = await signMetaTransactionAsync(mtx);
 | 
			
		||||
            const callOpts = {
 | 
			
		||||
                gasPrice: mtx.minGasPrice,
 | 
			
		||||
                value: mtx.value,
 | 
			
		||||
                value: 0,
 | 
			
		||||
            };
 | 
			
		||||
            const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts);
 | 
			
		||||
            expect(rawResult).to.eq(RAW_ORDER_SUCCESS_RESULT);
 | 
			
		||||
 
 | 
			
		||||
@@ -128,13 +128,22 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
 | 
			
		||||
    async function fillLimitOrderAsync(
 | 
			
		||||
        order: LimitOrder,
 | 
			
		||||
        fillAmount: BigNumber | number = order.takerAmount,
 | 
			
		||||
        _taker: string = taker,
 | 
			
		||||
        opts: Partial<{
 | 
			
		||||
            fillAmount: BigNumber | number;
 | 
			
		||||
            taker: string;
 | 
			
		||||
            protocolFee?: BigNumber | number;
 | 
			
		||||
        }> = {},
 | 
			
		||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
			
		||||
        const { fillAmount, taker: _taker, protocolFee } = {
 | 
			
		||||
            taker,
 | 
			
		||||
            fillAmount: order.takerAmount,
 | 
			
		||||
            ...opts,
 | 
			
		||||
        };
 | 
			
		||||
        await prepareBalancesForOrderAsync(order, _taker);
 | 
			
		||||
        const _protocolFee = protocolFee === undefined ? SINGLE_PROTOCOL_FEE : protocolFee;
 | 
			
		||||
        return zeroEx
 | 
			
		||||
            .fillLimitOrder(order, await order.getSignatureWithProviderAsync(env.provider), new BigNumber(fillAmount))
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: _taker, value: SINGLE_PROTOCOL_FEE });
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: _taker, value: _protocolFee });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    describe('getLimitOrderInfo()', () => {
 | 
			
		||||
@@ -200,7 +209,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            const fillAmount = order.takerAmount.minus(1);
 | 
			
		||||
            // Fill the order first.
 | 
			
		||||
            await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            const info = await zeroEx.getLimitOrderInfo(order).callAsync();
 | 
			
		||||
            assertOrderInfoEquals(info, {
 | 
			
		||||
                status: OrderStatus.Fillable,
 | 
			
		||||
@@ -226,7 +235,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            const fillAmount = order.takerAmount.minus(1);
 | 
			
		||||
            // Fill the order first.
 | 
			
		||||
            await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            await zeroEx.cancelLimitOrder(order).awaitTransactionSuccessAsync({ from: maker });
 | 
			
		||||
            const info = await zeroEx.getLimitOrderInfo(order).callAsync();
 | 
			
		||||
            assertOrderInfoEquals(info, {
 | 
			
		||||
@@ -245,7 +254,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
        await prepareBalancesForOrderAsync(order, _taker);
 | 
			
		||||
        return zeroEx
 | 
			
		||||
            .fillRfqOrder(order, await order.getSignatureWithProviderAsync(env.provider), new BigNumber(fillAmount))
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: _taker, value: SINGLE_PROTOCOL_FEE });
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: _taker });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    describe('getRfqOrderInfo()', () => {
 | 
			
		||||
@@ -287,9 +296,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            await prepareBalancesForOrderAsync(order);
 | 
			
		||||
            const sig = await order.getSignatureWithProviderAsync(env.provider);
 | 
			
		||||
            // Fill the order first.
 | 
			
		||||
            await zeroEx
 | 
			
		||||
                .fillRfqOrder(order, sig, order.takerAmount)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: SINGLE_PROTOCOL_FEE });
 | 
			
		||||
            await zeroEx.fillRfqOrder(order, sig, order.takerAmount).awaitTransactionSuccessAsync({ from: taker });
 | 
			
		||||
            // Advance time to expire the order.
 | 
			
		||||
            await env.web3Wrapper.increaseTimeAsync(61);
 | 
			
		||||
            const info = await zeroEx.getRfqOrderInfo(order).callAsync();
 | 
			
		||||
@@ -381,7 +388,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
 | 
			
		||||
        it('can cancel a partially filled order', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            await fillLimitOrderAsync(order, order.takerAmount.minus(1));
 | 
			
		||||
            await fillLimitOrderAsync(order, { fillAmount: order.takerAmount.minus(1) });
 | 
			
		||||
            const receipt = await zeroEx.cancelLimitOrder(order).awaitTransactionSuccessAsync({ from: maker });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
@@ -748,6 +755,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            takerTokenFilledAmount,
 | 
			
		||||
            takerTokenFeeFilledAmount,
 | 
			
		||||
        } = computeLimitOrderFilledAmounts(order, takerTokenFillAmount, takerTokenAlreadyFilledAmount);
 | 
			
		||||
        const protocolFee = order.taker !== NULL_ADDRESS ? ZERO_AMOUNT : SINGLE_PROTOCOL_FEE;
 | 
			
		||||
        return {
 | 
			
		||||
            taker,
 | 
			
		||||
            takerTokenFilledAmount,
 | 
			
		||||
@@ -758,16 +766,25 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            feeRecipient: order.feeRecipient,
 | 
			
		||||
            makerToken: order.makerToken,
 | 
			
		||||
            takerToken: order.takerToken,
 | 
			
		||||
            protocolFeePaid: SINGLE_PROTOCOL_FEE,
 | 
			
		||||
            protocolFeePaid: protocolFee,
 | 
			
		||||
            pool: order.pool,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async function assertExpectedFinalBalancesFromLimitOrderFillAsync(
 | 
			
		||||
        order: LimitOrder,
 | 
			
		||||
        takerTokenFillAmount: BigNumber = order.takerAmount,
 | 
			
		||||
        takerTokenAlreadyFilledAmount: BigNumber = ZERO_AMOUNT,
 | 
			
		||||
        opts: Partial<{
 | 
			
		||||
            takerTokenFillAmount: BigNumber;
 | 
			
		||||
            takerTokenAlreadyFilledAmount: BigNumber;
 | 
			
		||||
            receipt: TransactionReceiptWithDecodedLogs;
 | 
			
		||||
        }> = {},
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        const { takerTokenFillAmount, takerTokenAlreadyFilledAmount, receipt } = {
 | 
			
		||||
            takerTokenFillAmount: order.takerAmount,
 | 
			
		||||
            takerTokenAlreadyFilledAmount: ZERO_AMOUNT,
 | 
			
		||||
            receipt: undefined,
 | 
			
		||||
            ...opts,
 | 
			
		||||
        };
 | 
			
		||||
        const {
 | 
			
		||||
            makerTokenFilledAmount,
 | 
			
		||||
            takerTokenFilledAmount,
 | 
			
		||||
@@ -779,6 +796,13 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
        expect(makerBalance).to.bignumber.eq(takerTokenFilledAmount);
 | 
			
		||||
        expect(takerBalance).to.bignumber.eq(makerTokenFilledAmount);
 | 
			
		||||
        expect(feeRecipientBalance).to.bignumber.eq(takerTokenFeeFilledAmount);
 | 
			
		||||
        if (receipt) {
 | 
			
		||||
            const balanceOfTakerNow = await env.web3Wrapper.getBalanceInWeiAsync(taker);
 | 
			
		||||
            const balanceOfTakerBefore = await env.web3Wrapper.getBalanceInWeiAsync(taker, receipt.blockNumber - 1);
 | 
			
		||||
            const protocolFee = order.taker === NULL_ADDRESS ? SINGLE_PROTOCOL_FEE : 0;
 | 
			
		||||
            const totalCost = GAS_PRICE.times(receipt.gasUsed).plus(protocolFee);
 | 
			
		||||
            expect(balanceOfTakerBefore.minus(totalCost)).to.bignumber.eq(balanceOfTakerNow);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    describe('fillLimitOrder()', () => {
 | 
			
		||||
@@ -795,13 +819,13 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
                status: OrderStatus.Filled,
 | 
			
		||||
                takerTokenFilledAmount: order.takerAmount,
 | 
			
		||||
            });
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order);
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order, { receipt });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('can partially fill an order', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            const fillAmount = order.takerAmount.minus(1);
 | 
			
		||||
            const receipt = await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            const receipt = await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order, fillAmount)],
 | 
			
		||||
@@ -812,13 +836,13 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
                status: OrderStatus.Fillable,
 | 
			
		||||
                takerTokenFilledAmount: fillAmount,
 | 
			
		||||
            });
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order, fillAmount);
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order, { takerTokenFillAmount: fillAmount });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('can fully fill an order in two steps', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            let fillAmount = order.takerAmount.dividedToIntegerBy(2);
 | 
			
		||||
            let receipt = await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            let receipt = await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order, fillAmount)],
 | 
			
		||||
@@ -826,7 +850,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            );
 | 
			
		||||
            const alreadyFilledAmount = fillAmount;
 | 
			
		||||
            fillAmount = order.takerAmount.minus(fillAmount);
 | 
			
		||||
            receipt = await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            receipt = await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order, fillAmount, alreadyFilledAmount)],
 | 
			
		||||
@@ -842,7 +866,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
        it('clamps fill amount to remaining available', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            const fillAmount = order.takerAmount.plus(1);
 | 
			
		||||
            const receipt = await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            const receipt = await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order, fillAmount)],
 | 
			
		||||
@@ -853,13 +877,13 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
                status: OrderStatus.Filled,
 | 
			
		||||
                takerTokenFilledAmount: order.takerAmount,
 | 
			
		||||
            });
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order, fillAmount);
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order, { takerTokenFillAmount: fillAmount });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('clamps fill amount to remaining available in partial filled order', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            let fillAmount = order.takerAmount.dividedToIntegerBy(2);
 | 
			
		||||
            let receipt = await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            let receipt = await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order, fillAmount)],
 | 
			
		||||
@@ -867,7 +891,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            );
 | 
			
		||||
            const alreadyFilledAmount = fillAmount;
 | 
			
		||||
            fillAmount = order.takerAmount.minus(fillAmount).plus(1);
 | 
			
		||||
            receipt = await fillLimitOrderAsync(order, fillAmount);
 | 
			
		||||
            receipt = await fillLimitOrderAsync(order, { fillAmount });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order, fillAmount, alreadyFilledAmount)],
 | 
			
		||||
@@ -910,7 +934,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
 | 
			
		||||
        it('non-taker cannot fill order', async () => {
 | 
			
		||||
            const order = getTestLimitOrder({ taker });
 | 
			
		||||
            const tx = fillLimitOrderAsync(order, order.takerAmount, notTaker);
 | 
			
		||||
            const tx = fillLimitOrderAsync(order, { fillAmount: order.takerAmount, taker: notTaker });
 | 
			
		||||
            return expect(tx).to.revertWith(
 | 
			
		||||
                new RevertErrors.OrderNotFillableByTakerError(order.getHash(), notTaker, order.taker),
 | 
			
		||||
            );
 | 
			
		||||
@@ -918,7 +942,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
 | 
			
		||||
        it('non-sender cannot fill order', async () => {
 | 
			
		||||
            const order = getTestLimitOrder({ sender: taker });
 | 
			
		||||
            const tx = fillLimitOrderAsync(order, order.takerAmount, notTaker);
 | 
			
		||||
            const tx = fillLimitOrderAsync(order, { fillAmount: order.takerAmount, taker: notTaker });
 | 
			
		||||
            return expect(tx).to.revertWith(
 | 
			
		||||
                new RevertErrors.OrderNotFillableBySenderError(order.getHash(), notTaker, order.sender),
 | 
			
		||||
            );
 | 
			
		||||
@@ -934,7 +958,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('fails if no protocol fee attached (and no weth allowance)', async () => {
 | 
			
		||||
        it('fails if no protocol fee attached', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            await prepareBalancesForOrderAsync(order);
 | 
			
		||||
            const tx = zeroEx
 | 
			
		||||
@@ -948,6 +972,17 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            // token spender fallthroigh, so we won't get too specific.
 | 
			
		||||
            return expect(tx).to.revertWith(new AnyRevertError());
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('refunds excess protocol fee', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            const receipt = await fillLimitOrderAsync(order, { protocolFee: SINGLE_PROTOCOL_FEE.plus(1) });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [createLimitOrderFilledEventArgs(order)],
 | 
			
		||||
                IZeroExEvents.LimitOrderFilled,
 | 
			
		||||
            );
 | 
			
		||||
            await assertExpectedFinalBalancesFromLimitOrderFillAsync(order, { receipt });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    interface RfqOrderFilledAmounts {
 | 
			
		||||
@@ -993,7 +1028,6 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            maker: order.maker,
 | 
			
		||||
            makerToken: order.makerToken,
 | 
			
		||||
            takerToken: order.takerToken,
 | 
			
		||||
            protocolFeePaid: SINGLE_PROTOCOL_FEE,
 | 
			
		||||
            pool: order.pool,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
@@ -1170,6 +1204,14 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('non-taker cannot fill order', async () => {
 | 
			
		||||
            const order = getTestRfqOrder({ taker, txOrigin: notTaker });
 | 
			
		||||
            const tx = fillRfqOrderAsync(order, order.takerAmount, notTaker);
 | 
			
		||||
            return expect(tx).to.revertWith(
 | 
			
		||||
                new RevertErrors.OrderNotFillableByTakerError(order.getHash(), notTaker, order.taker),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('cannot fill an expired order', async () => {
 | 
			
		||||
            const order = getTestRfqOrder({ expiry: createExpiry(-60) });
 | 
			
		||||
            const tx = fillRfqOrderAsync(order);
 | 
			
		||||
@@ -1208,19 +1250,14 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('fails if no protocol fee attached (and no weth allowance)', async () => {
 | 
			
		||||
        it('fails if ETH is attached', async () => {
 | 
			
		||||
            const order = getTestRfqOrder();
 | 
			
		||||
            await prepareBalancesForOrderAsync(order);
 | 
			
		||||
            await prepareBalancesForOrderAsync(order, taker);
 | 
			
		||||
            const tx = zeroEx
 | 
			
		||||
                .fillRfqOrder(
 | 
			
		||||
                    order,
 | 
			
		||||
                    await order.getSignatureWithProviderAsync(env.provider),
 | 
			
		||||
                    new BigNumber(order.takerAmount),
 | 
			
		||||
                )
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: ZERO_AMOUNT });
 | 
			
		||||
            // The exact revert error depends on whether we are still doing a
 | 
			
		||||
            // token spender fallthrough, so we won't get too specific.
 | 
			
		||||
            return expect(tx).to.revertWith(new AnyRevertError());
 | 
			
		||||
                .fillRfqOrder(order, await order.getSignatureWithProviderAsync(env.provider), order.takerAmount)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: 1 });
 | 
			
		||||
            // This will revert at the language level because the fill function is not payable.
 | 
			
		||||
            return expect(tx).to.be.rejectedWith('revert');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -1249,6 +1286,18 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
                new RevertErrors.FillOrKillFailedError(order.getHash(), order.takerAmount, fillAmount),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('refunds excess protocol fee', async () => {
 | 
			
		||||
            const order = getTestLimitOrder();
 | 
			
		||||
            await prepareBalancesForOrderAsync(order);
 | 
			
		||||
            const takerBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(taker);
 | 
			
		||||
            const receipt = await zeroEx
 | 
			
		||||
                .fillOrKillLimitOrder(order, await order.getSignatureWithProviderAsync(env.provider), order.takerAmount)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: SINGLE_PROTOCOL_FEE.plus(1) });
 | 
			
		||||
            const takerBalanceAfter = await env.web3Wrapper.getBalanceInWeiAsync(taker);
 | 
			
		||||
            const totalCost = GAS_PRICE.times(receipt.gasUsed).plus(SINGLE_PROTOCOL_FEE);
 | 
			
		||||
            expect(takerBalanceBefore.minus(totalCost)).to.bignumber.eq(takerBalanceAfter);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('fillOrKillRfqOrder()', () => {
 | 
			
		||||
@@ -1257,7 +1306,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            await prepareBalancesForOrderAsync(order);
 | 
			
		||||
            const receipt = await zeroEx
 | 
			
		||||
                .fillOrKillRfqOrder(order, await order.getSignatureWithProviderAsync(env.provider), order.takerAmount)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: SINGLE_PROTOCOL_FEE });
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker });
 | 
			
		||||
            verifyEventsFromLogs(receipt.logs, [createRfqOrderFilledEventArgs(order)], IZeroExEvents.RfqOrderFilled);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -1267,11 +1316,21 @@ blockchainTests.resets('NativeOrdersFeature', env => {
 | 
			
		||||
            const fillAmount = order.takerAmount.plus(1);
 | 
			
		||||
            const tx = zeroEx
 | 
			
		||||
                .fillOrKillRfqOrder(order, await order.getSignatureWithProviderAsync(env.provider), fillAmount)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: SINGLE_PROTOCOL_FEE });
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker });
 | 
			
		||||
            return expect(tx).to.revertWith(
 | 
			
		||||
                new RevertErrors.FillOrKillFailedError(order.getHash(), order.takerAmount, fillAmount),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('fails if ETH is attached', async () => {
 | 
			
		||||
            const order = getTestRfqOrder();
 | 
			
		||||
            await prepareBalancesForOrderAsync(order);
 | 
			
		||||
            const tx = zeroEx
 | 
			
		||||
                .fillOrKillRfqOrder(order, await order.getSignatureWithProviderAsync(env.provider), order.takerAmount)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: taker, value: 1 });
 | 
			
		||||
            // This will revert at the language level because the fill function is not payable.
 | 
			
		||||
            return expect(tx).to.be.rejectedWith('revert');
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it.skip('RFQ gas benchmark', async () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -282,7 +282,7 @@ RFQ orders are a stripped down version of standard limit orders, supporting fewe
 | 
			
		||||
 | 
			
		||||
Some notable differences from regular limit orders are:
 | 
			
		||||
 | 
			
		||||
* The only fill restrictions that can be placed on an RFQ order is on the ``tx.origin`` of the transaction.
 | 
			
		||||
* The only fill restrictions that can be placed on an RFQ order is on the ``tx.origin`` and ``taker`` of the transaction.
 | 
			
		||||
* There are no taker token fees.
 | 
			
		||||
 | 
			
		||||
Structure
 | 
			
		||||
@@ -303,6 +303,8 @@ The ``RFQOrder`` struct has the following fields:
 | 
			
		||||
+-----------------+-------------+-----------------------------------------------------------------------------+
 | 
			
		||||
| ``maker``       | ``address`` | The address of the maker, and signer, of this order.                        |
 | 
			
		||||
+-----------------+-------------+-----------------------------------------------------------------------------+
 | 
			
		||||
| ``taker``       | ``address`` | Allowed taker address. Set to zero to allow any taker.                      |
 | 
			
		||||
+-----------------+-------------+-----------------------------------------------------------------------------+
 | 
			
		||||
| ``txOrigin``    | ``address`` | The allowed address of the EOA that submitted the Ethereum transaction.     |
 | 
			
		||||
+-----------------+-------------+-----------------------------------------------------------------------------+
 | 
			
		||||
| ``pool``        | ``bytes32`` | The staking pool to attribute the 0x protocol fee from this order.          |
 | 
			
		||||
@@ -348,6 +350,7 @@ The hash of the order is used to uniquely identify an order inside the protocol.
 | 
			
		||||
                'uint128 makerAmount,',
 | 
			
		||||
                'uint128 takerAmount,',
 | 
			
		||||
                'address maker,'
 | 
			
		||||
                'address taker,'
 | 
			
		||||
                'address txOrigin,'
 | 
			
		||||
                'bytes32 pool,',
 | 
			
		||||
                'uint64 expiry,',
 | 
			
		||||
@@ -359,6 +362,7 @@ The hash of the order is used to uniquely identify an order inside the protocol.
 | 
			
		||||
            order.makerAmount,
 | 
			
		||||
            order.takerAmount,
 | 
			
		||||
            order.maker,
 | 
			
		||||
            order.taker,
 | 
			
		||||
            order.txOrigin,
 | 
			
		||||
            order.pool,
 | 
			
		||||
            order.expiry,
 | 
			
		||||
@@ -421,7 +425,6 @@ RFQ orders can be filled with the ``fillRfqOrder()`` or ``fillOrKillRfqOrder()``
 | 
			
		||||
        uint128 takerTokenFillAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        // How much maker token from the order the taker received.
 | 
			
		||||
        returns (uint128 takerTokenFillAmount, uint128 makerTokenFillAmount);
 | 
			
		||||
 | 
			
		||||
@@ -438,7 +441,6 @@ RFQ orders can be filled with the ``fillRfqOrder()`` or ``fillOrKillRfqOrder()``
 | 
			
		||||
        uint128 takerTokenFillAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        // How much maker token from the order the taker received.
 | 
			
		||||
        returns (uint128 makerTokenFillAmount);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user