Compare commits
	
		
			26 Commits
		
	
	
		
			protocol@1
			...
			feat/721-o
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7bf1b0750e | ||
| 
						 | 
					2005054ec8 | ||
| 
						 | 
					cc70ad9d3c | ||
| 
						 | 
					db07fad051 | ||
| 
						 | 
					91bfce9145 | ||
| 
						 | 
					5fc608ed2f | ||
| 
						 | 
					9b626ee37a | ||
| 
						 | 
					4ae56d5876 | ||
| 
						 | 
					fd5d549c43 | ||
| 
						 | 
					180110de50 | ||
| 
						 | 
					d186cddc29 | ||
| 
						 | 
					fbabd2f264 | ||
| 
						 | 
					35f375a525 | ||
| 
						 | 
					29892db0fd | ||
| 
						 | 
					2cbb107380 | ||
| 
						 | 
					599d590fbc | ||
| 
						 | 
					9651b41264 | ||
| 
						 | 
					b6f118ef32 | ||
| 
						 | 
					2cc11c87d1 | ||
| 
						 | 
					7fa2eb4c2a | ||
| 
						 | 
					35d839c651 | ||
| 
						 | 
					a009779a88 | ||
| 
						 | 
					9aa7945bc4 | ||
| 
						 | 
					e7d198ef16 | ||
| 
						 | 
					4e7e6eb634 | ||
| 
						 | 
					f745023625 | 
@@ -34,6 +34,7 @@ import "./features/interfaces/IBatchFillNativeOrdersFeature.sol";
 | 
			
		||||
import "./features/interfaces/IMultiplexFeature.sol";
 | 
			
		||||
import "./features/interfaces/IOtcOrdersFeature.sol";
 | 
			
		||||
import "./features/interfaces/IFundRecoveryFeature.sol";
 | 
			
		||||
import "./features/interfaces/IERC721OrdersFeature.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev Interface for a fully featured Exchange Proxy.
 | 
			
		||||
@@ -50,7 +51,8 @@ interface IZeroEx is
 | 
			
		||||
    IBatchFillNativeOrdersFeature,
 | 
			
		||||
    IMultiplexFeature,
 | 
			
		||||
    IOtcOrdersFeature,
 | 
			
		||||
    IFundRecoveryFeature
 | 
			
		||||
    IFundRecoveryFeature,
 | 
			
		||||
    IERC721OrdersFeature
 | 
			
		||||
{
 | 
			
		||||
    // solhint-disable state-visibility
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,200 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
library LibERC721OrdersRichErrors {
 | 
			
		||||
 | 
			
		||||
    // solhint-disable func-name-mixedcase
 | 
			
		||||
 | 
			
		||||
    function OverspentEthError(
 | 
			
		||||
        uint256 ethSpent,
 | 
			
		||||
        uint256 msgValue
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("OverspentEthError(uint256,uint256)")),
 | 
			
		||||
            ethSpent,
 | 
			
		||||
            msgValue
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function InsufficientEthError(
 | 
			
		||||
        uint256 ethAvailable,
 | 
			
		||||
        uint256 orderAmount
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("InsufficientEthError(uint256,uint256)")),
 | 
			
		||||
            ethAvailable,
 | 
			
		||||
            orderAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function ERC721TokenMismatchError(
 | 
			
		||||
        address token1,
 | 
			
		||||
        address token2
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("ERC721TokenMismatchError(address,address)")),
 | 
			
		||||
            token1,
 | 
			
		||||
            token2
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function ERC20TokenMismatchError(
 | 
			
		||||
        address token1,
 | 
			
		||||
        address token2
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("ERC20TokenMismatchError(address,address)")),
 | 
			
		||||
            token1,
 | 
			
		||||
            token2
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function NegativeSpreadError(
 | 
			
		||||
        uint256 sellOrderAmount,
 | 
			
		||||
        uint256 buyOrderAmount
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("NegativeSpreadError(uint256,uint256)")),
 | 
			
		||||
            sellOrderAmount,
 | 
			
		||||
            buyOrderAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function SellOrderFeesExceedSpreadError(
 | 
			
		||||
        uint256 sellOrderFees,
 | 
			
		||||
        uint256 spread
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("SellOrderFeesExceedSpreadError(uint256,uint256)")),
 | 
			
		||||
            sellOrderFees,
 | 
			
		||||
            spread
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function OnlyTakerError(
 | 
			
		||||
        address sender,
 | 
			
		||||
        address taker
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("OnlyTakerError(address,address)")),
 | 
			
		||||
            sender,
 | 
			
		||||
            taker
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function InvalidSignerError(
 | 
			
		||||
        address maker,
 | 
			
		||||
        address signer
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("InvalidSignerError(address,address)")),
 | 
			
		||||
            maker,
 | 
			
		||||
            signer
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function OrderNotFillableError(
 | 
			
		||||
        address maker,
 | 
			
		||||
        uint256 nonce,
 | 
			
		||||
        uint8 orderStatus
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("OrderNotFillableError(address,uint256,uint8)")),
 | 
			
		||||
            maker,
 | 
			
		||||
            nonce,
 | 
			
		||||
            orderStatus
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function ERC721TokenIdMismatchError(
 | 
			
		||||
        uint256 tokenId,
 | 
			
		||||
        uint256 orderTokenId
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("ERC721TokenIdMismatchError(uint256,uint256)")),
 | 
			
		||||
            tokenId,
 | 
			
		||||
            orderTokenId
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function PropertyValidationFailedError(
 | 
			
		||||
        address propertyValidator,
 | 
			
		||||
        address erc721Token,
 | 
			
		||||
        uint256 erc721TokenId,
 | 
			
		||||
        bytes memory propertyData,
 | 
			
		||||
        bytes memory errorData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("PropertyValidationFailedError(address,address,uint256,bytes,bytes)")),
 | 
			
		||||
            propertyValidator,
 | 
			
		||||
            erc721Token,
 | 
			
		||||
            erc721TokenId,
 | 
			
		||||
            propertyData,
 | 
			
		||||
            errorData
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1138
									
								
								contracts/zero-ex/contracts/src/features/ERC721OrdersFeature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1138
									
								
								contracts/zero-ex/contracts/src/features/ERC721OrdersFeature.sol
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -311,7 +311,7 @@ contract OtcOrdersFeature is
 | 
			
		||||
        // Unwrap WETH
 | 
			
		||||
        WETH.withdraw(order.makerAmount);
 | 
			
		||||
        // Transfer ETH to taker
 | 
			
		||||
        _transferEth(taker, order.makerAmount);
 | 
			
		||||
        _transferEth(payable(taker), order.makerAmount);
 | 
			
		||||
 | 
			
		||||
        emit OtcOrderFilled(
 | 
			
		||||
            orderInfo.orderHash,
 | 
			
		||||
@@ -622,16 +622,4 @@ contract OtcOrdersFeature is
 | 
			
		||||
            [txOrigin]
 | 
			
		||||
            [nonceBucket];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _transferEth(address recipient, uint256 amount)
 | 
			
		||||
        private
 | 
			
		||||
    {
 | 
			
		||||
        // Transfer ETH to recipient
 | 
			
		||||
        (bool success, bytes memory revertData) =
 | 
			
		||||
            recipient.call{value: amount}("");
 | 
			
		||||
        // Revert on failure
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            revertData.rrevert();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,282 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../libs/LibERC721Order.sol";
 | 
			
		||||
import "../libs/LibSignature.sol";
 | 
			
		||||
import "../../vendor/IERC721Token.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev Feature for interacting with ERC721 orders.
 | 
			
		||||
interface IERC721OrdersFeature {
 | 
			
		||||
 | 
			
		||||
    /// @dev Emitted whenever an `ERC721Order` is filled.
 | 
			
		||||
    /// @param direction Whether the order is selling or
 | 
			
		||||
    ///        buying the ERC721 token.
 | 
			
		||||
    /// @param erc20Token The address of the ERC20 token.
 | 
			
		||||
    /// @param erc20TokenAmount The amount of ERC20 token
 | 
			
		||||
    ///        to sell or buy.
 | 
			
		||||
    /// @param erc721Token The address of the ERC721 token.
 | 
			
		||||
    /// @param erc721TokenId The ID of the ERC721 asset.
 | 
			
		||||
    /// @param maker The maker of the order.
 | 
			
		||||
    /// @param taker The taker of the order.
 | 
			
		||||
    /// @param nonce The unique maker nonce in the order.
 | 
			
		||||
    /// @param matcher If this order was matched with another using `matchERC721Orders()`,
 | 
			
		||||
    ///                this will be the address of the caller. If not, this will be `address(0)`.
 | 
			
		||||
    event ERC721OrderFilled(
 | 
			
		||||
        LibERC721Order.TradeDirection direction,
 | 
			
		||||
        IERC20TokenV06 erc20Token,
 | 
			
		||||
        uint256 erc20TokenAmount,
 | 
			
		||||
        IERC721Token erc721Token,
 | 
			
		||||
        uint256 erc721TokenId,
 | 
			
		||||
        address maker,
 | 
			
		||||
        address taker,
 | 
			
		||||
        uint256 nonce,
 | 
			
		||||
        address matcher
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev Emitted whenever an `ERC721Order` is cancelled.
 | 
			
		||||
    /// @param maker The maker of the order.
 | 
			
		||||
    /// @param nonce The nonce of the order that was cancelled.
 | 
			
		||||
    event ERC721OrderCancelled(
 | 
			
		||||
        address maker,
 | 
			
		||||
        uint256 nonce
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev Emitted when an `ERC721Order` is pre-signed.
 | 
			
		||||
    ///      Contains all the fields of the order.
 | 
			
		||||
    event ERC721OrderPreSigned(
 | 
			
		||||
        LibERC721Order.TradeDirection direction,
 | 
			
		||||
        IERC20TokenV06 erc20Token,
 | 
			
		||||
        uint256 erc20TokenAmount,
 | 
			
		||||
        IERC721Token erc721Token,
 | 
			
		||||
        uint256 erc721TokenId,
 | 
			
		||||
        LibERC721Order.Property[] erc721TokenProperties,
 | 
			
		||||
        LibERC721Order.Fee[] fees,
 | 
			
		||||
        address maker,
 | 
			
		||||
        address taker,
 | 
			
		||||
        uint256 expiry,
 | 
			
		||||
        uint256 nonce
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev Sells an ERC721 asset to fill the given order.
 | 
			
		||||
    /// @param buyOrder The ERC721 buy order.
 | 
			
		||||
    /// @param signature The order signature from the maker.
 | 
			
		||||
    /// @param erc721TokenId The ID of the ERC721 asset being
 | 
			
		||||
    ///        sold. If the given order specifies properties,
 | 
			
		||||
    ///        the asset must satisfy those properties. Otherwise,
 | 
			
		||||
    ///        it must equal the tokenId in the order.
 | 
			
		||||
    /// @param unwrapNativeToken If this parameter is true and the
 | 
			
		||||
    ///        ERC20 token of the order is e.g. WETH, unwraps the
 | 
			
		||||
    ///        token before transferring it to the taker.
 | 
			
		||||
    /// @param callbackData If this parameter is non-zero, invokes
 | 
			
		||||
    ///        `zeroExERC721OrderCallback` on `msg.sender` after
 | 
			
		||||
    ///        the ERC20 tokens have been transferred to `msg.sender`
 | 
			
		||||
    ///        but before transferring the ERC721 asset to the buyer.
 | 
			
		||||
    function sellERC721(
 | 
			
		||||
        LibERC721Order.ERC721Order calldata buyOrder,
 | 
			
		||||
        LibSignature.Signature calldata signature,
 | 
			
		||||
        uint256 erc721TokenId,
 | 
			
		||||
        bool unwrapNativeToken,
 | 
			
		||||
        bytes calldata callbackData
 | 
			
		||||
    )
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @dev Buys an ERC721 asset by filling the given order.
 | 
			
		||||
    /// @param sellOrder The ERC721 sell order.
 | 
			
		||||
    /// @param signature The order signature.
 | 
			
		||||
    /// @param callbackData If this parameter is non-zero, invokes
 | 
			
		||||
    ///        `zeroExERC721OrderCallback` on `msg.sender` after
 | 
			
		||||
    ///        the ERC721 asset has been transferred to `msg.sender`
 | 
			
		||||
    ///        but before transferring the ERC20 tokens to the seller.
 | 
			
		||||
    ///        Native tokens acquired during the callback can be used
 | 
			
		||||
    ///        to fill the order.
 | 
			
		||||
    function buyERC721(
 | 
			
		||||
        LibERC721Order.ERC721Order calldata sellOrder,
 | 
			
		||||
        LibSignature.Signature calldata signature,
 | 
			
		||||
        bytes calldata callbackData
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable;
 | 
			
		||||
 | 
			
		||||
    /// @dev Cancel a single ERC721 order by its nonce. The caller
 | 
			
		||||
    ///      should be the maker of the order. Silently succeeds if
 | 
			
		||||
    ///      an order with the same nonce has already been filled or
 | 
			
		||||
    ///      cancelled.
 | 
			
		||||
    /// @param orderNonce The order nonce.
 | 
			
		||||
    function cancelERC721Order(uint256 orderNonce)
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @dev Cancel multiple ERC721 orders by their nonces. The caller
 | 
			
		||||
    ///      should be the maker of the orders. Silently succeeds if
 | 
			
		||||
    ///      an order with the same nonce has already been filled or
 | 
			
		||||
    ///      cancelled.
 | 
			
		||||
    /// @param orderNonces The order nonces.
 | 
			
		||||
    function batchCancelERC721Orders(uint256[] calldata orderNonces)
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @dev Buys multiple ERC721 assets by filling the
 | 
			
		||||
    ///      given orders.
 | 
			
		||||
    /// @param sellOrders The ERC721 sell orders.
 | 
			
		||||
    /// @param signatures The order signatures.
 | 
			
		||||
    /// @param revertIfIncomplete If true, reverts if this
 | 
			
		||||
    ///        function fails to fill any individual order.
 | 
			
		||||
    /// @return successes An array of booleans corresponding to whether
 | 
			
		||||
    ///         each order in `orders` was successfully filled.
 | 
			
		||||
    function batchBuyERC721s(
 | 
			
		||||
        LibERC721Order.ERC721Order[] calldata sellOrders,
 | 
			
		||||
        LibSignature.Signature[] calldata signatures,
 | 
			
		||||
        bool revertIfIncomplete
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (bool[] memory successes);
 | 
			
		||||
 | 
			
		||||
    /// @dev Matches a pair of complementary orders that have
 | 
			
		||||
    ///      a non-negative spread. Each order is filled at
 | 
			
		||||
    ///      their respective price, and the matcher receives
 | 
			
		||||
    ///      a profit denominated in the ERC20 token.
 | 
			
		||||
    /// @param sellOrder Order selling an ERC721 asset.
 | 
			
		||||
    /// @param buyOrder Order buying an ERC721 asset.
 | 
			
		||||
    /// @param sellOrderSignature Signature for the sell order.
 | 
			
		||||
    /// @param buyOrderSignature Signature for the buy order.
 | 
			
		||||
    /// @return profit The amount of profit earned by the caller
 | 
			
		||||
    ///         of this function (denominated in the ERC20 token
 | 
			
		||||
    ///         of the matched orders).
 | 
			
		||||
    function matchERC721Orders(
 | 
			
		||||
        LibERC721Order.ERC721Order calldata sellOrder,
 | 
			
		||||
        LibERC721Order.ERC721Order calldata buyOrder,
 | 
			
		||||
        LibSignature.Signature calldata sellOrderSignature,
 | 
			
		||||
        LibSignature.Signature calldata buyOrderSignature
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (uint256 profit);
 | 
			
		||||
 | 
			
		||||
    /// @dev Matches pairs of complementary orders that have
 | 
			
		||||
    ///      non-negative spreads. Each order is filled at
 | 
			
		||||
    ///      their respective price, and the matcher receives
 | 
			
		||||
    ///      a profit denominated in the ERC20 token.
 | 
			
		||||
    /// @param sellOrders Orders selling ERC721 assets.
 | 
			
		||||
    /// @param buyOrders Orders buying ERC721 assets.
 | 
			
		||||
    /// @param sellOrderSignatures Signatures for the sell orders.
 | 
			
		||||
    /// @param buyOrderSignatures Signatures for the buy orders.
 | 
			
		||||
    /// @return profits The amount of profit earned by the caller
 | 
			
		||||
    ///         of this function for each pair of matched orders
 | 
			
		||||
    ///         (denominated in the ERC20 token of the order pair).
 | 
			
		||||
    /// @return successes An array of booleans corresponding to
 | 
			
		||||
    ///         whether each pair of orders was successfully matched.
 | 
			
		||||
    function batchMatchERC721Orders(
 | 
			
		||||
        LibERC721Order.ERC721Order[] calldata sellOrders,
 | 
			
		||||
        LibERC721Order.ERC721Order[] calldata buyOrders,
 | 
			
		||||
        LibSignature.Signature[] calldata sellOrderSignatures,
 | 
			
		||||
        LibSignature.Signature[] calldata buyOrderSignatures
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (uint256[] memory profits, bool[] memory successes);
 | 
			
		||||
 | 
			
		||||
    /// @dev Callback for the ERC721 `safeTransferFrom` function.
 | 
			
		||||
    ///      This callback can be used to sell an ERC721 asset if
 | 
			
		||||
    ///      a valid ERC721 order, signature and `unwrapNativeToken`
 | 
			
		||||
    ///      are encoded in `data`. This allows takers to sell their
 | 
			
		||||
    ///      ERC721 asset without first calling `setApprovalForAll`.
 | 
			
		||||
    /// @param operator The address which called `safeTransferFrom`.
 | 
			
		||||
    /// @param from The address which previously owned the token.
 | 
			
		||||
    /// @param tokenId The ID of the asset being transferred.
 | 
			
		||||
    /// @param data Additional data with no specified format. If a
 | 
			
		||||
    ///        valid ERC721 order, signature and `unwrapNativeToken`
 | 
			
		||||
    ///        are encoded in `data`, this function will try to fill
 | 
			
		||||
    ///        the order using the received asset.
 | 
			
		||||
    /// @return success The selector of this function (0x150b7a02),
 | 
			
		||||
    ///         indicating that the callback succeeded.
 | 
			
		||||
    function onERC721Received(
 | 
			
		||||
        address operator,
 | 
			
		||||
        address from,
 | 
			
		||||
        uint256 tokenId,
 | 
			
		||||
        bytes calldata data
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (bytes4 success);
 | 
			
		||||
 | 
			
		||||
    /// @dev Approves an ERC721 order on-chain. After pre-signing
 | 
			
		||||
    ///      the order, the `PRESIGNED` signature type will become
 | 
			
		||||
    ///      valid for that order and signer.
 | 
			
		||||
    /// @param order An ERC721 order.
 | 
			
		||||
    function preSignERC721Order(LibERC721Order.ERC721Order calldata order)
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @dev Checks whether the given signature is valid for the
 | 
			
		||||
    ///      the given ERC721 order. Reverts if not.
 | 
			
		||||
    /// @param order The ERC721 order.
 | 
			
		||||
    /// @param signature The signature to validate.
 | 
			
		||||
    function validateERC721OrderSignature(
 | 
			
		||||
        LibERC721Order.ERC721Order calldata order,
 | 
			
		||||
        LibSignature.Signature calldata signature
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view;
 | 
			
		||||
 | 
			
		||||
    /// @dev If the given order is buying an ERC721 asset, checks
 | 
			
		||||
    ///      whether or not the given token ID satisfies the required
 | 
			
		||||
    ///      properties specified in the order. If the order does not
 | 
			
		||||
    ///      specify any properties, this function instead checks
 | 
			
		||||
    ///      whether the given token ID matches the ID in the order.
 | 
			
		||||
    ///      Reverts if any checks fail, or if the order is selling
 | 
			
		||||
    ///      an ERC721 asset.
 | 
			
		||||
    /// @param order The ERC721 order.
 | 
			
		||||
    /// @param erc721TokenId The ID of the ERC721 asset.
 | 
			
		||||
    function validateERC721OrderProperties(
 | 
			
		||||
        LibERC721Order.ERC721Order calldata order,
 | 
			
		||||
        uint256 erc721TokenId
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view;
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the current status of an ERC721 order.
 | 
			
		||||
    /// @param order The ERC721 order.
 | 
			
		||||
    /// @return status The status of the order.
 | 
			
		||||
    function getERC721OrderStatus(LibERC721Order.ERC721Order calldata order)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (LibERC721Order.OrderStatus status);
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the canonical hash of an ERC721 order.
 | 
			
		||||
    /// @param order The ERC721 order.
 | 
			
		||||
    /// @return orderHash The order hash.
 | 
			
		||||
    function getERC721OrderHash(LibERC721Order.ERC721Order calldata order)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes32 orderHash);
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the order status bit vector for the given
 | 
			
		||||
    ///      maker address and nonce range.
 | 
			
		||||
    /// @param maker The maker of the order.
 | 
			
		||||
    /// @param nonceRange Order status bit vectors are indexed
 | 
			
		||||
    ///        by maker address and the upper 248 bits of the
 | 
			
		||||
    ///        order nonce. We define `nonceRange` to be these
 | 
			
		||||
    ///        248 bits.
 | 
			
		||||
    /// @return bitVector The order status bit vector for the
 | 
			
		||||
    ///         given maker and nonce range.
 | 
			
		||||
    function getERC721OrderStatusBitVector(address maker, uint248 nonceRange)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 bitVector);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										267
									
								
								contracts/zero-ex/contracts/src/features/libs/LibERC721Order.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								contracts/zero-ex/contracts/src/features/libs/LibERC721Order.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,267 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
import "../../vendor/IERC721Token.sol";
 | 
			
		||||
import "../../vendor/IPropertyValidator.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev A library for common ERC721 order operations.
 | 
			
		||||
library LibERC721Order {
 | 
			
		||||
    using LibSafeMathV06 for uint256;
 | 
			
		||||
    using LibRichErrorsV06 for bytes;
 | 
			
		||||
 | 
			
		||||
    enum OrderStatus {
 | 
			
		||||
        INVALID,
 | 
			
		||||
        FILLABLE,
 | 
			
		||||
        UNFILLABLE,
 | 
			
		||||
        EXPIRED
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum TradeDirection {
 | 
			
		||||
        SELL_721,
 | 
			
		||||
        BUY_721
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct Property {
 | 
			
		||||
        IPropertyValidator propertyValidator;
 | 
			
		||||
        bytes propertyData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct Fee {
 | 
			
		||||
        address recipient;
 | 
			
		||||
        uint256 amount;
 | 
			
		||||
        bytes feeData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev An ERC721<>ERC20 limit order.
 | 
			
		||||
    struct ERC721Order {
 | 
			
		||||
        TradeDirection direction;
 | 
			
		||||
        IERC20TokenV06 erc20Token;
 | 
			
		||||
        uint256 erc20TokenAmount;
 | 
			
		||||
        IERC721Token erc721Token;
 | 
			
		||||
        uint256 erc721TokenId;
 | 
			
		||||
        Property[] erc721TokenProperties;
 | 
			
		||||
        Fee[] fees;
 | 
			
		||||
        address maker;
 | 
			
		||||
        address taker;
 | 
			
		||||
        uint256 expiry;
 | 
			
		||||
        uint256 nonce;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The type hash for ERC721 orders, which is:
 | 
			
		||||
    // keccak256(abi.encodePacked(
 | 
			
		||||
    //     "ERC721Order(",
 | 
			
		||||
    //       "uint8 direction,",
 | 
			
		||||
    //       "address erc20Token,",
 | 
			
		||||
    //       "uint256 erc20TokenAmount,",
 | 
			
		||||
    //       "address erc721Token,",
 | 
			
		||||
    //       "uint256 erc721TokenId,",
 | 
			
		||||
    //       "Property[] erc721TokenProperties,",
 | 
			
		||||
    //       "Fee[] fees,",
 | 
			
		||||
    //       "address maker,",
 | 
			
		||||
    //       "address taker,",
 | 
			
		||||
    //       "uint256 expiry,",
 | 
			
		||||
    //       "uint256 nonce",
 | 
			
		||||
    //     ")",
 | 
			
		||||
    //     "Fee(",
 | 
			
		||||
    //       "address recipient,",
 | 
			
		||||
    //       "uint256 amount,",
 | 
			
		||||
    //       "bytes feeData",
 | 
			
		||||
    //     ")",
 | 
			
		||||
    //     "Property(",
 | 
			
		||||
    //       "address propertyValidator,",
 | 
			
		||||
    //       "bytes propertyData",
 | 
			
		||||
    //     ")"
 | 
			
		||||
    // ))
 | 
			
		||||
    uint256 private constant _ERC_721_ORDER_TYPEHASH =
 | 
			
		||||
        0x7af652c2504c5c7d806f4f25edc3762dd8478099f694981f8802db656a9ba9d8;
 | 
			
		||||
 | 
			
		||||
    // keccak256(abi.encodePacked(
 | 
			
		||||
    //     "Fee(",
 | 
			
		||||
    //       "address recipient,",
 | 
			
		||||
    //       "uint256 amount,",
 | 
			
		||||
    //       "bytes feeData",
 | 
			
		||||
    //     ")"
 | 
			
		||||
    // ))
 | 
			
		||||
    uint256 private constant _FEE_TYPEHASH =
 | 
			
		||||
        0xe68c29f1b4e8cce0bbcac76eb1334bdc1dc1f293a517c90e9e532340e1e94115;
 | 
			
		||||
 | 
			
		||||
    // keccak256(abi.encodePacked(
 | 
			
		||||
    //     "Property(",
 | 
			
		||||
    //       "address propertyValidator,",
 | 
			
		||||
    //       "bytes propertyData",
 | 
			
		||||
    //     ")"
 | 
			
		||||
    // ))
 | 
			
		||||
    uint256 private constant _PROPERTY_TYPEHASH =
 | 
			
		||||
        0x6292cf854241cb36887e639065eca63b3af9f7f70270cebeda4c29b6d3bc65e8;
 | 
			
		||||
 | 
			
		||||
    // keccak256("");
 | 
			
		||||
    bytes32 private constant _EMPTY_ARRAY_KECCAK256 =
 | 
			
		||||
        0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
 | 
			
		||||
 | 
			
		||||
    // keccak256(abi.encodePacked(keccak256(abi.encode(
 | 
			
		||||
    //     _PROPERTY_TYPEHASH,
 | 
			
		||||
    //     address(0),
 | 
			
		||||
    //     keccak256("")
 | 
			
		||||
    // ))));
 | 
			
		||||
    bytes32 private constant _NULL_PROPERTY_STRUCT_HASH =
 | 
			
		||||
        0x720ee400a9024f6a49768142c339bf09d2dd9056ab52d20fbe7165faba6e142d;
 | 
			
		||||
 | 
			
		||||
    uint256 private constant ADDRESS_MASK = (1 << 160) - 1;
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the struct hash of an ERC721 order.
 | 
			
		||||
    /// @param order The ERC721 order.
 | 
			
		||||
    /// @return structHash The struct hash of the order.
 | 
			
		||||
    function getERC721OrderStructHash(ERC721Order memory order)
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes32 structHash)
 | 
			
		||||
    {
 | 
			
		||||
        // We give `order.erc721TokenProperties.length == 0` and
 | 
			
		||||
        // `order.erc721TokenProperties.length == 1` special treatment
 | 
			
		||||
        // because we expect these to be the most common.
 | 
			
		||||
        bytes32 propertiesHash;
 | 
			
		||||
        if (order.erc721TokenProperties.length == 0) {
 | 
			
		||||
            propertiesHash = _EMPTY_ARRAY_KECCAK256;
 | 
			
		||||
        } else if (order.erc721TokenProperties.length == 1) {
 | 
			
		||||
            Property memory property = order
 | 
			
		||||
                .erc721TokenProperties[0];
 | 
			
		||||
            if (
 | 
			
		||||
                address(property.propertyValidator) == address(0) &&
 | 
			
		||||
                property.propertyData.length == 0
 | 
			
		||||
            ) {
 | 
			
		||||
                propertiesHash = _NULL_PROPERTY_STRUCT_HASH;
 | 
			
		||||
            } else {
 | 
			
		||||
                // propertiesHash = keccak256(abi.encodePacked(keccak256(abi.encode(
 | 
			
		||||
                //     _PROPERTY_TYPEHASH,
 | 
			
		||||
                //     order.erc721TokenProperties[0].propertyValidator,
 | 
			
		||||
                //     keccak256(order.erc721TokenProperties[0].propertyData)
 | 
			
		||||
                // ))));
 | 
			
		||||
                bytes32 dataHash = keccak256(property.propertyData);
 | 
			
		||||
                assembly {
 | 
			
		||||
                    // Load free memory pointer
 | 
			
		||||
                    let mem := mload(64)
 | 
			
		||||
                    mstore(mem, _PROPERTY_TYPEHASH)
 | 
			
		||||
                    // property.propertyValidator
 | 
			
		||||
                    mstore(add(mem, 32), and(ADDRESS_MASK, mload(property)))
 | 
			
		||||
                    // keccak256(property.propertyData)
 | 
			
		||||
                    mstore(add(mem, 64), dataHash)
 | 
			
		||||
                    mstore(mem, keccak256(mem, 96))
 | 
			
		||||
                    propertiesHash := keccak256(mem, 32)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            bytes32[] memory propertyStructHashArray = new bytes32[](
 | 
			
		||||
                order.erc721TokenProperties.length
 | 
			
		||||
            );
 | 
			
		||||
            for (uint256 i = 0; i < order.erc721TokenProperties.length; i++) {
 | 
			
		||||
                propertyStructHashArray[i] = keccak256(abi.encode(
 | 
			
		||||
                    _PROPERTY_TYPEHASH,
 | 
			
		||||
                    order.erc721TokenProperties[i].propertyValidator,
 | 
			
		||||
                    keccak256(order.erc721TokenProperties[i].propertyData)
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
            propertiesHash = keccak256(abi.encodePacked(propertyStructHashArray));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // We give `order.fees.length == 0` and
 | 
			
		||||
        // `order.fees.length == 1` special treatment
 | 
			
		||||
        // because we expect these to be the most common.
 | 
			
		||||
        bytes32 feesHash;
 | 
			
		||||
        if (order.fees.length == 0) {
 | 
			
		||||
            feesHash = _EMPTY_ARRAY_KECCAK256;
 | 
			
		||||
        } else if (order.fees.length == 1) {
 | 
			
		||||
            // feesHash = keccak256(abi.encodePacked(keccak256(abi.encode(
 | 
			
		||||
            //     _FEE_TYPEHASH,
 | 
			
		||||
            //     order.fees[0].recipient,
 | 
			
		||||
            //     order.fees[0].amount,
 | 
			
		||||
            //     keccak256(order.fees[0].feeData)
 | 
			
		||||
            // ))));
 | 
			
		||||
            Fee memory fee = order.fees[0];
 | 
			
		||||
            bytes32 dataHash = keccak256(fee.feeData);
 | 
			
		||||
            assembly {
 | 
			
		||||
                // Load free memory pointer
 | 
			
		||||
                let mem := mload(64)
 | 
			
		||||
                mstore(mem, _FEE_TYPEHASH)
 | 
			
		||||
                // fee.recipient
 | 
			
		||||
                mstore(add(mem, 32), and(ADDRESS_MASK, mload(fee)))
 | 
			
		||||
                // fee.amount
 | 
			
		||||
                mstore(add(mem, 64), mload(add(fee, 32)))
 | 
			
		||||
                // keccak256(fee.feeData)
 | 
			
		||||
                mstore(add(mem, 96), dataHash)
 | 
			
		||||
                mstore(mem, keccak256(mem, 128))
 | 
			
		||||
                feesHash := keccak256(mem, 32)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            bytes32[] memory feeStructHashArray = new bytes32[](order.fees.length);
 | 
			
		||||
            for (uint256 i = 0; i < order.fees.length; i++) {
 | 
			
		||||
                feeStructHashArray[i] = keccak256(abi.encode(
 | 
			
		||||
                    _FEE_TYPEHASH,
 | 
			
		||||
                    order.fees[i].recipient,
 | 
			
		||||
                    order.fees[i].amount,
 | 
			
		||||
                    keccak256(order.fees[i].feeData)
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
            feesHash = keccak256(abi.encodePacked(feeStructHashArray));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Hash in place, equivalent to:
 | 
			
		||||
        // return keccak256(abi.encode(
 | 
			
		||||
        //     _ERC_721_ORDER_TYPEHASH,
 | 
			
		||||
        //     order.direction,
 | 
			
		||||
        //     order.erc20Token,
 | 
			
		||||
        //     order.erc20TokenAmount,
 | 
			
		||||
        //     order.erc721Token,
 | 
			
		||||
        //     order.erc721TokenId,
 | 
			
		||||
        //     propertiesHash,
 | 
			
		||||
        //     feesHash,
 | 
			
		||||
        //     order.maker,
 | 
			
		||||
        //     order.taker,
 | 
			
		||||
        //     order.expiry,
 | 
			
		||||
        //     order.nonce
 | 
			
		||||
        // ));
 | 
			
		||||
        assembly {
 | 
			
		||||
            if lt(order, 32) { invalid() } // Don't underflow memory.
 | 
			
		||||
 | 
			
		||||
            let typeHashPos := sub(order, 32) // order + (32 * -1)
 | 
			
		||||
            let propertiesHashPos := add(order, 160) // order + (32 * 5)
 | 
			
		||||
            let feesHashPos := add(order, 192) // order + (32 * 6)
 | 
			
		||||
 | 
			
		||||
            let temp1 := mload(typeHashPos)
 | 
			
		||||
            let temp2 := mload(propertiesHashPos)
 | 
			
		||||
            let temp3 := mload(feesHashPos)
 | 
			
		||||
 | 
			
		||||
            mstore(typeHashPos, _ERC_721_ORDER_TYPEHASH)
 | 
			
		||||
            mstore(propertiesHashPos, propertiesHash)
 | 
			
		||||
            mstore(feesHashPos, feesHash)
 | 
			
		||||
            structHash := keccak256(typeHashPos, 384 /* 32 * 12 */ )
 | 
			
		||||
 | 
			
		||||
            mstore(typeHashPos, temp1)
 | 
			
		||||
            mstore(propertiesHashPos, temp2)
 | 
			
		||||
            mstore(feesHashPos, temp3)
 | 
			
		||||
        }
 | 
			
		||||
        return structHash;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -44,7 +44,8 @@ library LibSignature {
 | 
			
		||||
        ILLEGAL,
 | 
			
		||||
        INVALID,
 | 
			
		||||
        EIP712,
 | 
			
		||||
        ETHSIGN
 | 
			
		||||
        ETHSIGN,
 | 
			
		||||
        PRESIGNED
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Encoded EC signature.
 | 
			
		||||
@@ -146,6 +147,15 @@ library LibSignature {
 | 
			
		||||
            ).rrevert();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If a feature supports pre-signing, it wouldn't use 
 | 
			
		||||
        // `getSignerOfHash` on a pre-signed order.
 | 
			
		||||
        if (signature.signatureType == SignatureType.PRESIGNED) {
 | 
			
		||||
            LibSignatureRichErrors.SignatureValidationError(
 | 
			
		||||
                LibSignatureRichErrors.SignatureValidationErrorCodes.UNSUPPORTED,
 | 
			
		||||
                hash
 | 
			
		||||
            ).rrevert();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Solidity should check that the signature type is within enum range for us
 | 
			
		||||
        // when abi-decoding.
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -622,15 +622,6 @@ contract MultiplexFeature is
 | 
			
		||||
            _executeBatchSell(batchSellParams).boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Transfers some amount of ETH to the given recipient and
 | 
			
		||||
    // reverts if the transfer fails.
 | 
			
		||||
    function _transferEth(address payable recipient, uint256 amount)
 | 
			
		||||
        private
 | 
			
		||||
    {
 | 
			
		||||
        (bool success,) = recipient.call{value: amount}("");
 | 
			
		||||
        require(success, "MultiplexFeature::_transferEth/TRANSFER_FAILED");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This function computes the "target" address of hop index `i` within
 | 
			
		||||
    // a multi-hop sell.
 | 
			
		||||
    // If `i == 0`, the target is the address which should hold the input
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,74 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
import "../vendor/IERC721Token.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev Helpers for moving ERC721 assets around.
 | 
			
		||||
abstract contract FixinERC721Spender {
 | 
			
		||||
 | 
			
		||||
    // Mask of the lower 20 bytes of a bytes32.
 | 
			
		||||
    uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
 | 
			
		||||
 | 
			
		||||
    /// @dev Transfers an ERC721 asset from `owner` to `to`.
 | 
			
		||||
    /// @param token The address of the ERC721 token contract.
 | 
			
		||||
    /// @param owner The owner of the asset.
 | 
			
		||||
    /// @param to The recipient of the asset.
 | 
			
		||||
    /// @param tokenId The token ID of the asset to transfer.
 | 
			
		||||
    function _transferERC721AssetFrom(
 | 
			
		||||
        IERC721Token token,
 | 
			
		||||
        address owner,
 | 
			
		||||
        address to,
 | 
			
		||||
        uint256 tokenId
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
    {
 | 
			
		||||
        require(address(token) != address(this), "FixinERC721Spender/CANNOT_INVOKE_SELF");
 | 
			
		||||
 | 
			
		||||
        assembly {
 | 
			
		||||
            let ptr := mload(0x40) // free memory pointer
 | 
			
		||||
 | 
			
		||||
            // selector for transferFrom(address,address,uint256)
 | 
			
		||||
            mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
 | 
			
		||||
            mstore(add(ptr, 0x04), and(owner, ADDRESS_MASK))
 | 
			
		||||
            mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
 | 
			
		||||
            mstore(add(ptr, 0x44), tokenId)
 | 
			
		||||
 | 
			
		||||
            let success := call(
 | 
			
		||||
                gas(),
 | 
			
		||||
                and(token, ADDRESS_MASK),
 | 
			
		||||
                0,
 | 
			
		||||
                ptr,
 | 
			
		||||
                0x64,
 | 
			
		||||
                0,
 | 
			
		||||
                0
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            if iszero(success) {
 | 
			
		||||
                let rdsize := returndatasize()
 | 
			
		||||
                returndatacopy(ptr, 0, rdsize)
 | 
			
		||||
                revert(ptr, rdsize)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -141,6 +141,20 @@ abstract contract FixinTokenSpender {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /// @dev Transfers some amount of ETH to the given recipient and
 | 
			
		||||
    ///      reverts if the transfer fails.
 | 
			
		||||
    /// @param recipient The recipient of the ETH.
 | 
			
		||||
    /// @param amount The amount of ETH to transfer.
 | 
			
		||||
    function _transferEth(address payable recipient, uint256 amount)
 | 
			
		||||
        internal
 | 
			
		||||
    {
 | 
			
		||||
        if (amount > 0) {
 | 
			
		||||
            (bool success,) = recipient.call{value: amount}("");
 | 
			
		||||
            require(success, "FixinTokenSpender::_transferEth/TRANSFER_FAILED");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Gets the maximum amount of an ERC20 token `token` that can be
 | 
			
		||||
    ///      pulled from `owner` by this address.
 | 
			
		||||
    /// @param token The token to spend.
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,47 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./LibStorage.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev Storage helpers for `ERC721OrdersFeature`.
 | 
			
		||||
library LibERC721OrdersStorage {
 | 
			
		||||
 | 
			
		||||
    /// @dev Storage bucket for this feature.
 | 
			
		||||
    struct Storage {
 | 
			
		||||
        // maker => nonce range => order status bit vector
 | 
			
		||||
        mapping(address => mapping(uint248 => uint256)) orderStatusByMaker;
 | 
			
		||||
        // order hash => maker => isSigned
 | 
			
		||||
        mapping(bytes32 => mapping(address => bool)) preSigned;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the storage bucket for this contract.
 | 
			
		||||
    function getStorage() internal pure returns (Storage storage stor) {
 | 
			
		||||
        uint256 storageSlot = LibStorage.getStorageSlot(
 | 
			
		||||
            LibStorage.StorageId.ERC721Orders
 | 
			
		||||
        );
 | 
			
		||||
        // Dip into assembly to change the slot pointed to by the local
 | 
			
		||||
        // variable `stor`.
 | 
			
		||||
        // See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries
 | 
			
		||||
        assembly { stor_slot := storageSlot }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -39,7 +39,8 @@ library LibStorage {
 | 
			
		||||
        MetaTransactions,
 | 
			
		||||
        ReentrancyGuard,
 | 
			
		||||
        NativeOrders,
 | 
			
		||||
        OtcOrders
 | 
			
		||||
        OtcOrders,
 | 
			
		||||
        ERC721Orders
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Get the storage slot given a storage ID. We assign unique, well-spaced
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								contracts/zero-ex/contracts/src/vendor/IERC721OrderCallback.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								contracts/zero-ex/contracts/src/vendor/IERC721OrderCallback.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IERC721OrderCallback {
 | 
			
		||||
 | 
			
		||||
    /// @dev A taker callback function invoked in the ERC721Feature between 
 | 
			
		||||
    ///      the maker -> taker transfer and the taker -> maker transfer.
 | 
			
		||||
    /// @param callbackData Arbitrary data used by this callback.
 | 
			
		||||
    /// @return success The selector of this function (0x6d46db51), 
 | 
			
		||||
    ///         indicating that the callback succeeded.
 | 
			
		||||
    function zeroExERC721OrderCallback(bytes calldata callbackData)
 | 
			
		||||
        external
 | 
			
		||||
        returns (bytes4 success);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										159
									
								
								contracts/zero-ex/contracts/src/vendor/IERC721Token.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								contracts/zero-ex/contracts/src/vendor/IERC721Token.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IERC721Token {
 | 
			
		||||
 | 
			
		||||
    /// @dev This emits when ownership of any NFT changes by any mechanism.
 | 
			
		||||
    ///      This event emits when NFTs are created (`from` == 0) and destroyed
 | 
			
		||||
    ///      (`to` == 0). Exception: during contract creation, any number of NFTs
 | 
			
		||||
    ///      may be created and assigned without emitting Transfer. At the time of
 | 
			
		||||
    ///      any transfer, the approved address for that NFT (if any) is reset to none.
 | 
			
		||||
    event Transfer(
 | 
			
		||||
        address indexed _from,
 | 
			
		||||
        address indexed _to,
 | 
			
		||||
        uint256 indexed _tokenId
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev This emits when the approved address for an NFT is changed or
 | 
			
		||||
    ///      reaffirmed. The zero address indicates there is no approved address.
 | 
			
		||||
    ///      When a Transfer event emits, this also indicates that the approved
 | 
			
		||||
    ///      address for that NFT (if any) is reset to none.
 | 
			
		||||
    event Approval(
 | 
			
		||||
        address indexed _owner,
 | 
			
		||||
        address indexed _approved,
 | 
			
		||||
        uint256 indexed _tokenId
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev This emits when an operator is enabled or disabled for an owner.
 | 
			
		||||
    ///      The operator can manage all NFTs of the owner.
 | 
			
		||||
    event ApprovalForAll(
 | 
			
		||||
        address indexed _owner,
 | 
			
		||||
        address indexed _operator,
 | 
			
		||||
        bool _approved
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @notice Transfers the ownership of an NFT from one address to another address
 | 
			
		||||
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
 | 
			
		||||
    ///      perator, or the approved address for this NFT. Throws if `_from` is
 | 
			
		||||
    ///      not the current owner. Throws if `_to` is the zero address. Throws if
 | 
			
		||||
    ///      `_tokenId` is not a valid NFT. When transfer is complete, this function
 | 
			
		||||
    ///      checks if `_to` is a smart contract (code size > 0). If so, it calls
 | 
			
		||||
    ///      `onERC721Received` on `_to` and throws if the return value is not
 | 
			
		||||
    ///      `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
 | 
			
		||||
    /// @param _from The current owner of the NFT
 | 
			
		||||
    /// @param _to The new owner
 | 
			
		||||
    /// @param _tokenId The NFT to transfer
 | 
			
		||||
    /// @param _data Additional data with no specified format, sent in call to `_to`
 | 
			
		||||
    function safeTransferFrom(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId,
 | 
			
		||||
        bytes calldata _data
 | 
			
		||||
    )
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @notice Transfers the ownership of an NFT from one address to another address
 | 
			
		||||
    /// @dev This works identically to the other function with an extra data parameter,
 | 
			
		||||
    ///      except this function just sets data to "".
 | 
			
		||||
    /// @param _from The current owner of the NFT
 | 
			
		||||
    /// @param _to The new owner
 | 
			
		||||
    /// @param _tokenId The NFT to transfer
 | 
			
		||||
    function safeTransferFrom(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId
 | 
			
		||||
    )
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @notice Change or reaffirm the approved address for an NFT
 | 
			
		||||
    /// @dev The zero address indicates there is no approved address.
 | 
			
		||||
    ///      Throws unless `msg.sender` is the current NFT owner, or an authorized
 | 
			
		||||
    ///      operator of the current owner.
 | 
			
		||||
    /// @param _approved The new approved NFT controller
 | 
			
		||||
    /// @param _tokenId The NFT to approve
 | 
			
		||||
    function approve(address _approved, uint256 _tokenId)
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @notice Enable or disable approval for a third party ("operator") to manage
 | 
			
		||||
    ///         all of `msg.sender`'s assets
 | 
			
		||||
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
 | 
			
		||||
    ///      multiple operators per owner.
 | 
			
		||||
    /// @param _operator Address to add to the set of authorized operators
 | 
			
		||||
    /// @param _approved True if the operator is approved, false to revoke approval
 | 
			
		||||
    function setApprovalForAll(address _operator, bool _approved)
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @notice Count all NFTs assigned to an owner
 | 
			
		||||
    /// @dev NFTs assigned to the zero address are considered invalid, and this
 | 
			
		||||
    ///      function throws for queries about the zero address.
 | 
			
		||||
    /// @param _owner An address for whom to query the balance
 | 
			
		||||
    /// @return The number of NFTs owned by `_owner`, possibly zero
 | 
			
		||||
    function balanceOf(address _owner)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256);
 | 
			
		||||
 | 
			
		||||
    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
 | 
			
		||||
    ///         TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
 | 
			
		||||
    ///         THEY MAY BE PERMANENTLY LOST
 | 
			
		||||
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
 | 
			
		||||
    ///      operator, or the approved address for this NFT. Throws if `_from` is
 | 
			
		||||
    ///      not the current owner. Throws if `_to` is the zero address. Throws if
 | 
			
		||||
    ///      `_tokenId` is not a valid NFT.
 | 
			
		||||
    /// @param _from The current owner of the NFT
 | 
			
		||||
    /// @param _to The new owner
 | 
			
		||||
    /// @param _tokenId The NFT to transfer
 | 
			
		||||
    function transferFrom(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId
 | 
			
		||||
    )
 | 
			
		||||
        external;
 | 
			
		||||
 | 
			
		||||
    /// @notice Find the owner of an NFT
 | 
			
		||||
    /// @dev NFTs assigned to zero address are considered invalid, and queries
 | 
			
		||||
    ///      about them do throw.
 | 
			
		||||
    /// @param _tokenId The identifier for an NFT
 | 
			
		||||
    /// @return The address of the owner of the NFT
 | 
			
		||||
    function ownerOf(uint256 _tokenId)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (address);
 | 
			
		||||
 | 
			
		||||
    /// @notice Get the approved address for a single NFT
 | 
			
		||||
    /// @dev Throws if `_tokenId` is not a valid NFT.
 | 
			
		||||
    /// @param _tokenId The NFT to find the approved address for
 | 
			
		||||
    /// @return The approved address for this NFT, or the zero address if there is none
 | 
			
		||||
    function getApproved(uint256 _tokenId) 
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (address);
 | 
			
		||||
    
 | 
			
		||||
    /// @notice Query if an address is an authorized operator for another address
 | 
			
		||||
    /// @param _owner The address that owns the NFTs
 | 
			
		||||
    /// @param _operator The address that acts on behalf of the owner
 | 
			
		||||
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
 | 
			
		||||
    function isApprovedForAll(address _owner, address _operator)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (bool);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								contracts/zero-ex/contracts/src/vendor/IFeeRecipient.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								contracts/zero-ex/contracts/src/vendor/IFeeRecipient.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IFeeRecipient {
 | 
			
		||||
 | 
			
		||||
    /// @dev A callback function invoked in the ERC721Feature for each ERC721
 | 
			
		||||
    ///      order fee that get paid. Integrators can make use of this callback
 | 
			
		||||
    ///      to implement arbitrary fee-handling logic, e.g. splitting the fee
 | 
			
		||||
    ///      between multiple parties.
 | 
			
		||||
    /// @param tokenAddress The address of the token in which the received fee is
 | 
			
		||||
    ///        denominated. `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` indicates
 | 
			
		||||
    ///        that the fee was paid in the native token (e.g. ETH).
 | 
			
		||||
    /// @param amount The amount of the given token received.
 | 
			
		||||
    /// @param feeData Arbitrary data encoded in the `Fee` used by this callback.
 | 
			
		||||
    /// @return success The selector of this function (0x0190805e),
 | 
			
		||||
    ///         indicating that the callback succeeded.
 | 
			
		||||
    function receiveZeroExFeeCallback(
 | 
			
		||||
        address tokenAddress,
 | 
			
		||||
        uint256 amount,
 | 
			
		||||
        bytes calldata feeData
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (bytes4 success);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								contracts/zero-ex/contracts/src/vendor/IPropertyValidator.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								contracts/zero-ex/contracts/src/vendor/IPropertyValidator.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IPropertyValidator {
 | 
			
		||||
 | 
			
		||||
    /// @dev Checks that the given ERC721/ERC1155 asset satisfies the properties encoded in `propertyData`.
 | 
			
		||||
    ///      Should revert if the asset does not satisfy the specified properties.
 | 
			
		||||
    /// @param tokenAddress The ERC721/ERC1155 token contract address.
 | 
			
		||||
    /// @param tokenId The ERC721/ERC1155 tokenId of the asset to check.
 | 
			
		||||
    /// @param propertyData Encoded properties or auxiliary data needed to perform the check.
 | 
			
		||||
    function validateProperty(
 | 
			
		||||
        address tokenAddress,
 | 
			
		||||
        uint256 tokenId,
 | 
			
		||||
        bytes calldata propertyData
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,61 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../src/IZeroEx.sol";
 | 
			
		||||
import "../src/vendor/IERC721Token.sol";
 | 
			
		||||
import "../src/features/libs/LibERC721Order.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestERC721OrderPresigner {
 | 
			
		||||
    IZeroEx private immutable zeroEx;
 | 
			
		||||
 | 
			
		||||
    constructor(IZeroEx _zeroEx)
 | 
			
		||||
        public
 | 
			
		||||
    {
 | 
			
		||||
        zeroEx = _zeroEx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function approveERC721(IERC721Token token)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        token.setApprovalForAll(address(zeroEx), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function approveERC20(IERC20TokenV06 token)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        token.approve(address(zeroEx), uint256(-1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function preSignOrder(LibERC721Order.ERC721Order calldata order)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        zeroEx.preSignERC721Order(order);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function cancelOrder(uint256 orderNonce)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        zeroEx.cancelERC721Order(orderNonce);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								contracts/zero-ex/contracts/test/TestFeeRecipient.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								contracts/zero-ex/contracts/test/TestFeeRecipient.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestFeeRecipient {
 | 
			
		||||
    bytes4 constant private SUCCESS = this.receiveZeroExFeeCallback.selector;
 | 
			
		||||
    bytes4 constant private FAILURE = 0xdeadbeef;
 | 
			
		||||
 | 
			
		||||
    uint256 constant private TRIGGER_REVERT = 333;
 | 
			
		||||
    uint256 constant private TRIGGER_FAILURE = 666;
 | 
			
		||||
 | 
			
		||||
    event FeeReceived(
 | 
			
		||||
        address tokenAddress,
 | 
			
		||||
        uint256 amount
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    receive() external payable {}
 | 
			
		||||
 | 
			
		||||
    function receiveZeroExFeeCallback(
 | 
			
		||||
        address tokenAddress,
 | 
			
		||||
        uint256 amount,
 | 
			
		||||
        bytes calldata /* feeData */
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (bytes4 success)
 | 
			
		||||
    {
 | 
			
		||||
        emit FeeReceived(tokenAddress, amount);
 | 
			
		||||
        if (amount == TRIGGER_REVERT) {
 | 
			
		||||
            revert("TestFeeRecipient::receiveZeroExFeeCallback/REVERT");
 | 
			
		||||
        } else if (amount == TRIGGER_FAILURE) {
 | 
			
		||||
            return FAILURE;
 | 
			
		||||
        } else {
 | 
			
		||||
            return SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,7 +22,7 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
 | 
			
		||||
import "../src/vendor/v3/IERC20Bridge.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "./tokens/TestMintableERC20Token.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestFillQuoteTransformerBridge {
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "./tokens/TestMintableERC20Token.sol";
 | 
			
		||||
import "../src/features/libs/LibNativeOrder.sol";
 | 
			
		||||
import "../src/features/libs/LibSignature.sol";
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "../src/transformers/IERC20Transformer.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "./tokens/TestMintableERC20Token.sol";
 | 
			
		||||
import "./TestTransformerHost.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../src/transformers/IERC20Transformer.sol";
 | 
			
		||||
import "../src/transformers/LibERC20Transformer.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "./tokens/TestMintableERC20Token.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestMintTokenERC20Transformer is
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								contracts/zero-ex/contracts/test/TestPropertyValidator.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								contracts/zero-ex/contracts/test/TestPropertyValidator.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestPropertyValidator {
 | 
			
		||||
 | 
			
		||||
    function validateProperty(
 | 
			
		||||
        address tokenAddress,
 | 
			
		||||
        uint256 tokenId,
 | 
			
		||||
        bytes calldata propertyData
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            propertyData.length > 0,
 | 
			
		||||
            "TestPropertyValidator::validateProperty/REVERT"
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -21,9 +21,9 @@ pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "../src/transformers/IERC20Transformer.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "./tokens/TestMintableERC20Token.sol";
 | 
			
		||||
import "./TestTransformerHost.sol";
 | 
			
		||||
import "./TestWeth.sol";
 | 
			
		||||
import "./tokens/TestWeth.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestWethTransformerHost is
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "../tokens/TestMintableERC20Token.sol";
 | 
			
		||||
 | 
			
		||||
contract TestCurve {
 | 
			
		||||
 | 
			
		||||
@@ -21,7 +21,7 @@ pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "./TestMintableERC20Token.sol";
 | 
			
		||||
import "../tokens/TestMintableERC20Token.sol";
 | 
			
		||||
 | 
			
		||||
contract TestMooniswap {
 | 
			
		||||
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../src/vendor/IUniswapV2Pair.sol";
 | 
			
		||||
import "../../src/vendor/IUniswapV2Pair.sol";
 | 
			
		||||
 | 
			
		||||
interface IUniswapV2PoolDeployer {
 | 
			
		||||
    struct CreationParameters {
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../src/vendor/IUniswapV3Pool.sol";
 | 
			
		||||
import "../../src/vendor/IUniswapV3Pool.sol";
 | 
			
		||||
 | 
			
		||||
interface IUniswapV3PoolDeployer {
 | 
			
		||||
    struct CreationParameters {
 | 
			
		||||
@@ -0,0 +1,385 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 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.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IERC721Receiver {
 | 
			
		||||
 | 
			
		||||
    /// @notice Handle the receipt of an NFT
 | 
			
		||||
    /// @dev The ERC721 smart contract calls this function on the recipient
 | 
			
		||||
    ///  after a `transfer`. This function MAY throw to revert and reject the
 | 
			
		||||
    ///  transfer. Return of other than the magic value MUST result in the
 | 
			
		||||
    ///  transaction being reverted.
 | 
			
		||||
    ///  Note: the contract address is always the message sender.
 | 
			
		||||
    /// @param _operator The address which called `safeTransferFrom` function
 | 
			
		||||
    /// @param _from The address which previously owned the token
 | 
			
		||||
    /// @param _tokenId The NFT identifier which is being transferred
 | 
			
		||||
    /// @param _data Additional data with no specified format
 | 
			
		||||
    /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
 | 
			
		||||
    ///  unless throwing
 | 
			
		||||
    function onERC721Received(
 | 
			
		||||
        address _operator,
 | 
			
		||||
        address _from,
 | 
			
		||||
        uint256 _tokenId,
 | 
			
		||||
        bytes calldata _data
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (bytes4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract TestMintableERC721Token {
 | 
			
		||||
    using LibSafeMathV06 for uint256;
 | 
			
		||||
 | 
			
		||||
    /// @dev This emits when ownership of any NFT changes by any mechanism.
 | 
			
		||||
    ///      This event emits when NFTs are created (`from` == 0) and destroyed
 | 
			
		||||
    ///      (`to` == 0). Exception: during contract creation, any number of NFTs
 | 
			
		||||
    ///      may be created and assigned without emitting Transfer. At the time of
 | 
			
		||||
    ///      any transfer, the approved address for that NFT (if any) is reset to none.
 | 
			
		||||
    event Transfer(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev This emits when the approved address for an NFT is changed or
 | 
			
		||||
    ///      reaffirmed. The zero address indicates there is no approved address.
 | 
			
		||||
    ///      When a Transfer event emits, this also indicates that the approved
 | 
			
		||||
    ///      address for that NFT (if any) is reset to none.
 | 
			
		||||
    event Approval(
 | 
			
		||||
        address indexed _owner,
 | 
			
		||||
        address indexed _approved,
 | 
			
		||||
        uint256 indexed _tokenId
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    /// @dev This emits when an operator is enabled or disabled for an owner.
 | 
			
		||||
    ///      The operator can manage all NFTs of the owner.
 | 
			
		||||
    event ApprovalForAll(
 | 
			
		||||
        address indexed _owner,
 | 
			
		||||
        address indexed _operator,
 | 
			
		||||
        bool _approved
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Function selector for ERC721Receiver.onERC721Received
 | 
			
		||||
    // 0x150b7a02
 | 
			
		||||
    bytes4 constant private ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
 | 
			
		||||
 | 
			
		||||
    // Mapping of tokenId => owner
 | 
			
		||||
    mapping (uint256 => address) private owners;
 | 
			
		||||
 | 
			
		||||
    // Mapping of tokenId => approved address
 | 
			
		||||
    mapping (uint256 => address) private approvals;
 | 
			
		||||
 | 
			
		||||
    // Mapping of owner => number of tokens owned
 | 
			
		||||
    mapping (address => uint256) private balances;
 | 
			
		||||
 | 
			
		||||
    // Mapping of owner => operator => approved
 | 
			
		||||
    mapping (address => mapping (address => bool)) private operatorApprovals;
 | 
			
		||||
 | 
			
		||||
    /// @dev Function to mint a new token
 | 
			
		||||
    ///      Reverts if the given token ID already exists
 | 
			
		||||
    /// @param _to Address of the beneficiary that will own the minted token
 | 
			
		||||
    /// @param _tokenId ID of the token to be minted by the msg.sender    
 | 
			
		||||
    function mint(address _to, uint256 _tokenId)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            _to != address(0),
 | 
			
		||||
            "ERC721_ZERO_TO_ADDRESS"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        address owner = owners[_tokenId];
 | 
			
		||||
        require(
 | 
			
		||||
            owner == address(0),
 | 
			
		||||
            "ERC721_OWNER_ALREADY_EXISTS"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        owners[_tokenId] = _to;
 | 
			
		||||
        balances[_to] = balances[_to].safeAdd(1);
 | 
			
		||||
 | 
			
		||||
        emit Transfer(
 | 
			
		||||
            address(0),
 | 
			
		||||
            _to,
 | 
			
		||||
            _tokenId
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Function to burn a token
 | 
			
		||||
    ///      Reverts if the given token ID doesn't exist
 | 
			
		||||
    /// @param _owner Owner of token with given token ID
 | 
			
		||||
    /// @param _tokenId ID of the token to be burned by the msg.sender
 | 
			
		||||
    function burn(address _owner, uint256 _tokenId)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            _owner != address(0),
 | 
			
		||||
            "ERC721_ZERO_OWNER_ADDRESS"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        address owner = owners[_tokenId];
 | 
			
		||||
        require(
 | 
			
		||||
            owner == _owner,
 | 
			
		||||
            "ERC721_OWNER_MISMATCH"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        owners[_tokenId] = address(0);
 | 
			
		||||
        balances[_owner] = balances[_owner].safeSub(1);
 | 
			
		||||
 | 
			
		||||
        emit Transfer(
 | 
			
		||||
            _owner,
 | 
			
		||||
            address(0),
 | 
			
		||||
            _tokenId
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Transfers the ownership of an NFT from one address to another address
 | 
			
		||||
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
 | 
			
		||||
    ///      operator, or the approved address for this NFT. Throws if `_from` is
 | 
			
		||||
    ///      not the current owner. Throws if `_to` is the zero address. Throws if
 | 
			
		||||
    ///      `_tokenId` is not a valid NFT. When transfer is complete, this function
 | 
			
		||||
    ///      checks if `_to` is a smart contract (code size > 0). If so, it calls
 | 
			
		||||
    ///      `onERC721Received` on `_to` and throws if the return value is not
 | 
			
		||||
    ///      `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
 | 
			
		||||
    /// @param _from The current owner of the NFT
 | 
			
		||||
    /// @param _to The new owner
 | 
			
		||||
    /// @param _tokenId The NFT to transfer
 | 
			
		||||
    /// @param _data Additional data with no specified format, sent in call to `_to`
 | 
			
		||||
    function safeTransferFrom(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId,
 | 
			
		||||
        bytes calldata _data
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        transferFrom(
 | 
			
		||||
            _from,
 | 
			
		||||
            _to,
 | 
			
		||||
            _tokenId
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        uint256 receiverCodeSize;
 | 
			
		||||
        assembly {
 | 
			
		||||
            receiverCodeSize := extcodesize(_to)
 | 
			
		||||
        }
 | 
			
		||||
        if (receiverCodeSize > 0) {
 | 
			
		||||
            bytes4 selector = IERC721Receiver(_to).onERC721Received(
 | 
			
		||||
                msg.sender,
 | 
			
		||||
                _from,
 | 
			
		||||
                _tokenId,
 | 
			
		||||
                _data
 | 
			
		||||
            );
 | 
			
		||||
            require(
 | 
			
		||||
                selector == ERC721_RECEIVED,
 | 
			
		||||
                "ERC721_INVALID_SELECTOR"
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Transfers the ownership of an NFT from one address to another address
 | 
			
		||||
    /// @dev This works identically to the other function with an extra data parameter,
 | 
			
		||||
    ///      except this function just sets data to "".
 | 
			
		||||
    /// @param _from The current owner of the NFT
 | 
			
		||||
    /// @param _to The new owner
 | 
			
		||||
    /// @param _tokenId The NFT to transfer
 | 
			
		||||
    function safeTransferFrom(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        transferFrom(
 | 
			
		||||
            _from,
 | 
			
		||||
            _to,
 | 
			
		||||
            _tokenId
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        uint256 receiverCodeSize;
 | 
			
		||||
        assembly {
 | 
			
		||||
            receiverCodeSize := extcodesize(_to)
 | 
			
		||||
        }
 | 
			
		||||
        if (receiverCodeSize > 0) {
 | 
			
		||||
            bytes4 selector = IERC721Receiver(_to).onERC721Received(
 | 
			
		||||
                msg.sender,
 | 
			
		||||
                _from,
 | 
			
		||||
                _tokenId,
 | 
			
		||||
                ""
 | 
			
		||||
            );
 | 
			
		||||
            require(
 | 
			
		||||
                selector == ERC721_RECEIVED,
 | 
			
		||||
                "ERC721_INVALID_SELECTOR"
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Change or reaffirm the approved address for an NFT
 | 
			
		||||
    /// @dev The zero address indicates there is no approved address.
 | 
			
		||||
    ///      Throws unless `msg.sender` is the current NFT owner, or an authorized
 | 
			
		||||
    ///      operator of the current owner.
 | 
			
		||||
    /// @param _approved The new approved NFT controller
 | 
			
		||||
    /// @param _tokenId The NFT to approve
 | 
			
		||||
    function approve(address _approved, uint256 _tokenId)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        address owner = ownerOf(_tokenId);
 | 
			
		||||
        require(
 | 
			
		||||
            msg.sender == owner || isApprovedForAll(owner, msg.sender),
 | 
			
		||||
            "ERC721_INVALID_SENDER"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        approvals[_tokenId] = _approved;
 | 
			
		||||
        emit Approval(
 | 
			
		||||
            owner,
 | 
			
		||||
            _approved,
 | 
			
		||||
            _tokenId
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Enable or disable approval for a third party ("operator") to manage
 | 
			
		||||
    ///         all of `msg.sender`'s assets
 | 
			
		||||
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
 | 
			
		||||
    ///      multiple operators per owner.
 | 
			
		||||
    /// @param _operator Address to add to the set of authorized operators
 | 
			
		||||
    /// @param _approved True if the operator is approved, false to revoke approval
 | 
			
		||||
    function setApprovalForAll(address _operator, bool _approved)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        operatorApprovals[msg.sender][_operator] = _approved;
 | 
			
		||||
        emit ApprovalForAll(
 | 
			
		||||
            msg.sender,
 | 
			
		||||
            _operator,
 | 
			
		||||
            _approved
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Count all NFTs assigned to an owner
 | 
			
		||||
    /// @dev NFTs assigned to the zero address are considered invalid, and this
 | 
			
		||||
    ///      function throws for queries about the zero address.
 | 
			
		||||
    /// @param _owner An address for whom to query the balance
 | 
			
		||||
    /// @return The number of NFTs owned by `_owner`, possibly zero
 | 
			
		||||
    function balanceOf(address _owner)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256)
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            _owner != address(0),
 | 
			
		||||
            "ERC721_ZERO_OWNER"
 | 
			
		||||
        );
 | 
			
		||||
        return balances[_owner];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
 | 
			
		||||
    ///         TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
 | 
			
		||||
    ///         THEY MAY BE PERMANENTLY LOST
 | 
			
		||||
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
 | 
			
		||||
    ///      operator, or the approved address for this NFT. Throws if `_from` is
 | 
			
		||||
    ///      not the current owner. Throws if `_to` is the zero address. Throws if
 | 
			
		||||
    ///      `_tokenId` is not a valid NFT.
 | 
			
		||||
    /// @param _from The current owner of the NFT
 | 
			
		||||
    /// @param _to The new owner
 | 
			
		||||
    /// @param _tokenId The NFT to transfer
 | 
			
		||||
    function transferFrom(
 | 
			
		||||
        address _from,
 | 
			
		||||
        address _to,
 | 
			
		||||
        uint256 _tokenId
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            _to != address(0),
 | 
			
		||||
            "ERC721_ZERO_TO_ADDRESS"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        address owner = ownerOf(_tokenId);
 | 
			
		||||
        require(
 | 
			
		||||
            _from == owner,
 | 
			
		||||
            "ERC721_OWNER_MISMATCH"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        address spender = msg.sender;
 | 
			
		||||
        address approvedAddress = getApproved(_tokenId);
 | 
			
		||||
        require(
 | 
			
		||||
            spender == owner ||
 | 
			
		||||
            isApprovedForAll(owner, spender) ||
 | 
			
		||||
            approvedAddress == spender,
 | 
			
		||||
            "ERC721_INVALID_SPENDER"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (approvedAddress != address(0)) {
 | 
			
		||||
            approvals[_tokenId] = address(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        owners[_tokenId] = _to;
 | 
			
		||||
        balances[_from] = balances[_from].safeSub(1);
 | 
			
		||||
        balances[_to] = balances[_to].safeAdd(1);
 | 
			
		||||
 | 
			
		||||
        emit Transfer(
 | 
			
		||||
            _from,
 | 
			
		||||
            _to,
 | 
			
		||||
            _tokenId
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Find the owner of an NFT
 | 
			
		||||
    /// @dev NFTs assigned to zero address are considered invalid, and queries
 | 
			
		||||
    ///      about them do throw.
 | 
			
		||||
    /// @param _tokenId The identifier for an NFT
 | 
			
		||||
    /// @return The address of the owner of the NFT
 | 
			
		||||
    function ownerOf(uint256 _tokenId)
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (address)
 | 
			
		||||
    {
 | 
			
		||||
        address owner = owners[_tokenId];
 | 
			
		||||
        require(
 | 
			
		||||
            owner != address(0),
 | 
			
		||||
            "ERC721_ZERO_OWNER"
 | 
			
		||||
        );
 | 
			
		||||
        return owner;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Get the approved address for a single NFT
 | 
			
		||||
    /// @dev Throws if `_tokenId` is not a valid NFT.
 | 
			
		||||
    /// @param _tokenId The NFT to find the approved address for
 | 
			
		||||
    /// @return The approved address for this NFT, or the zero address if there is none
 | 
			
		||||
    function getApproved(uint256 _tokenId)
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (address)
 | 
			
		||||
    {
 | 
			
		||||
        return approvals[_tokenId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @notice Query if an address is an authorized operator for another address
 | 
			
		||||
    /// @param _owner The address that owns the NFTs
 | 
			
		||||
    /// @param _operator The address that acts on behalf of the owner
 | 
			
		||||
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
 | 
			
		||||
    function isApprovedForAll(address _owner, address _operator)
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (bool)
 | 
			
		||||
    {
 | 
			
		||||
        return operatorApprovals[_owner][_operator];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -43,7 +43,7 @@
 | 
			
		||||
    "config": {
 | 
			
		||||
        "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
 | 
			
		||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IERC721OrderCallback|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibERC721Order|LibERC721OrdersRichErrors|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestERC721OrderPresigner|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
			
		||||
    },
 | 
			
		||||
    "repository": {
 | 
			
		||||
        "type": "git",
 | 
			
		||||
 
 | 
			
		||||
@@ -11,11 +11,13 @@ import * as BootstrapFeature from '../test/generated-artifacts/BootstrapFeature.
 | 
			
		||||
import * as BridgeAdapter from '../test/generated-artifacts/BridgeAdapter.json';
 | 
			
		||||
import * as BridgeProtocols from '../test/generated-artifacts/BridgeProtocols.json';
 | 
			
		||||
import * as CurveLiquidityProvider from '../test/generated-artifacts/CurveLiquidityProvider.json';
 | 
			
		||||
import * as ERC721OrdersFeature from '../test/generated-artifacts/ERC721OrdersFeature.json';
 | 
			
		||||
import * as FeeCollector from '../test/generated-artifacts/FeeCollector.json';
 | 
			
		||||
import * as FeeCollectorController from '../test/generated-artifacts/FeeCollectorController.json';
 | 
			
		||||
import * as FillQuoteTransformer from '../test/generated-artifacts/FillQuoteTransformer.json';
 | 
			
		||||
import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json';
 | 
			
		||||
import * as FixinEIP712 from '../test/generated-artifacts/FixinEIP712.json';
 | 
			
		||||
import * as FixinERC721Spender from '../test/generated-artifacts/FixinERC721Spender.json';
 | 
			
		||||
import * as FixinProtocolFees from '../test/generated-artifacts/FixinProtocolFees.json';
 | 
			
		||||
import * as FixinReentrancyGuard from '../test/generated-artifacts/FixinReentrancyGuard.json';
 | 
			
		||||
import * as FixinTokenSpender from '../test/generated-artifacts/FixinTokenSpender.json';
 | 
			
		||||
@@ -27,7 +29,11 @@ import * as IBootstrapFeature from '../test/generated-artifacts/IBootstrapFeatur
 | 
			
		||||
import * as IBridgeAdapter from '../test/generated-artifacts/IBridgeAdapter.json';
 | 
			
		||||
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
 | 
			
		||||
import * as IERC20Transformer from '../test/generated-artifacts/IERC20Transformer.json';
 | 
			
		||||
import * as IERC721OrderCallback from '../test/generated-artifacts/IERC721OrderCallback.json';
 | 
			
		||||
import * as IERC721OrdersFeature from '../test/generated-artifacts/IERC721OrdersFeature.json';
 | 
			
		||||
import * as IERC721Token from '../test/generated-artifacts/IERC721Token.json';
 | 
			
		||||
import * as IFeature from '../test/generated-artifacts/IFeature.json';
 | 
			
		||||
import * as IFeeRecipient from '../test/generated-artifacts/IFeeRecipient.json';
 | 
			
		||||
import * as IFlashWallet from '../test/generated-artifacts/IFlashWallet.json';
 | 
			
		||||
import * as IFundRecoveryFeature from '../test/generated-artifacts/IFundRecoveryFeature.json';
 | 
			
		||||
import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json';
 | 
			
		||||
@@ -42,6 +48,7 @@ import * as InitialMigration from '../test/generated-artifacts/InitialMigration.
 | 
			
		||||
import * as IOtcOrdersFeature from '../test/generated-artifacts/IOtcOrdersFeature.json';
 | 
			
		||||
import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json';
 | 
			
		||||
import * as IPancakeSwapFeature from '../test/generated-artifacts/IPancakeSwapFeature.json';
 | 
			
		||||
import * as IPropertyValidator from '../test/generated-artifacts/IPropertyValidator.json';
 | 
			
		||||
import * as ISimpleFunctionRegistryFeature from '../test/generated-artifacts/ISimpleFunctionRegistryFeature.json';
 | 
			
		||||
import * as IStaking from '../test/generated-artifacts/IStaking.json';
 | 
			
		||||
import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json';
 | 
			
		||||
@@ -55,6 +62,9 @@ import * as IZeroEx from '../test/generated-artifacts/IZeroEx.json';
 | 
			
		||||
import * as LibBootstrap from '../test/generated-artifacts/LibBootstrap.json';
 | 
			
		||||
import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json';
 | 
			
		||||
import * as LibERC20Transformer from '../test/generated-artifacts/LibERC20Transformer.json';
 | 
			
		||||
import * as LibERC721Order from '../test/generated-artifacts/LibERC721Order.json';
 | 
			
		||||
import * as LibERC721OrdersRichErrors from '../test/generated-artifacts/LibERC721OrdersRichErrors.json';
 | 
			
		||||
import * as LibERC721OrdersStorage from '../test/generated-artifacts/LibERC721OrdersStorage.json';
 | 
			
		||||
import * as LibFeeCollector from '../test/generated-artifacts/LibFeeCollector.json';
 | 
			
		||||
import * as LibLiquidityProviderRichErrors from '../test/generated-artifacts/LibLiquidityProviderRichErrors.json';
 | 
			
		||||
import * as LibMetaTransactionsRichErrors from '../test/generated-artifacts/LibMetaTransactionsRichErrors.json';
 | 
			
		||||
@@ -129,7 +139,9 @@ import * as TestBridge from '../test/generated-artifacts/TestBridge.json';
 | 
			
		||||
import * as TestCallTarget from '../test/generated-artifacts/TestCallTarget.json';
 | 
			
		||||
import * as TestCurve from '../test/generated-artifacts/TestCurve.json';
 | 
			
		||||
import * as TestDelegateCaller from '../test/generated-artifacts/TestDelegateCaller.json';
 | 
			
		||||
import * as TestERC721OrderPresigner from '../test/generated-artifacts/TestERC721OrderPresigner.json';
 | 
			
		||||
import * as TestFeeCollectorController from '../test/generated-artifacts/TestFeeCollectorController.json';
 | 
			
		||||
import * as TestFeeRecipient from '../test/generated-artifacts/TestFeeRecipient.json';
 | 
			
		||||
import * as TestFillQuoteTransformerBridge from '../test/generated-artifacts/TestFillQuoteTransformerBridge.json';
 | 
			
		||||
import * as TestFillQuoteTransformerExchange from '../test/generated-artifacts/TestFillQuoteTransformerExchange.json';
 | 
			
		||||
import * as TestFillQuoteTransformerHost from '../test/generated-artifacts/TestFillQuoteTransformerHost.json';
 | 
			
		||||
@@ -144,6 +156,7 @@ import * as TestMetaTransactionsNativeOrdersFeature from '../test/generated-arti
 | 
			
		||||
import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json';
 | 
			
		||||
import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
 | 
			
		||||
import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json';
 | 
			
		||||
import * as TestMintableERC721Token from '../test/generated-artifacts/TestMintableERC721Token.json';
 | 
			
		||||
import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json';
 | 
			
		||||
import * as TestMooniswap from '../test/generated-artifacts/TestMooniswap.json';
 | 
			
		||||
import * as TestNativeOrdersFeature from '../test/generated-artifacts/TestNativeOrdersFeature.json';
 | 
			
		||||
@@ -151,6 +164,7 @@ import * as TestNoEthRecipient from '../test/generated-artifacts/TestNoEthRecipi
 | 
			
		||||
import * as TestOrderSignerRegistryWithContractWallet from '../test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json';
 | 
			
		||||
import * as TestPermissionlessTransformerDeployerSuicidal from '../test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json';
 | 
			
		||||
import * as TestPermissionlessTransformerDeployerTransformer from '../test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json';
 | 
			
		||||
import * as TestPropertyValidator from '../test/generated-artifacts/TestPropertyValidator.json';
 | 
			
		||||
import * as TestRfqOriginRegistration from '../test/generated-artifacts/TestRfqOriginRegistration.json';
 | 
			
		||||
import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json';
 | 
			
		||||
import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json';
 | 
			
		||||
@@ -181,6 +195,7 @@ export const artifacts = {
 | 
			
		||||
    ZeroEx: ZeroEx as ContractArtifact,
 | 
			
		||||
    ZeroExOptimized: ZeroExOptimized as ContractArtifact,
 | 
			
		||||
    LibCommonRichErrors: LibCommonRichErrors as ContractArtifact,
 | 
			
		||||
    LibERC721OrdersRichErrors: LibERC721OrdersRichErrors as ContractArtifact,
 | 
			
		||||
    LibLiquidityProviderRichErrors: LibLiquidityProviderRichErrors as ContractArtifact,
 | 
			
		||||
    LibMetaTransactionsRichErrors: LibMetaTransactionsRichErrors as ContractArtifact,
 | 
			
		||||
    LibNativeOrdersRichErrors: LibNativeOrdersRichErrors as ContractArtifact,
 | 
			
		||||
@@ -201,6 +216,7 @@ export const artifacts = {
 | 
			
		||||
    TransformerDeployer: TransformerDeployer as ContractArtifact,
 | 
			
		||||
    BatchFillNativeOrdersFeature: BatchFillNativeOrdersFeature as ContractArtifact,
 | 
			
		||||
    BootstrapFeature: BootstrapFeature as ContractArtifact,
 | 
			
		||||
    ERC721OrdersFeature: ERC721OrdersFeature as ContractArtifact,
 | 
			
		||||
    FundRecoveryFeature: FundRecoveryFeature as ContractArtifact,
 | 
			
		||||
    LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact,
 | 
			
		||||
    MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact,
 | 
			
		||||
@@ -214,6 +230,7 @@ export const artifacts = {
 | 
			
		||||
    UniswapV3Feature: UniswapV3Feature as ContractArtifact,
 | 
			
		||||
    IBatchFillNativeOrdersFeature: IBatchFillNativeOrdersFeature as ContractArtifact,
 | 
			
		||||
    IBootstrapFeature: IBootstrapFeature as ContractArtifact,
 | 
			
		||||
    IERC721OrdersFeature: IERC721OrdersFeature as ContractArtifact,
 | 
			
		||||
    IFeature: IFeature as ContractArtifact,
 | 
			
		||||
    IFundRecoveryFeature: IFundRecoveryFeature as ContractArtifact,
 | 
			
		||||
    ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact,
 | 
			
		||||
@@ -229,6 +246,7 @@ export const artifacts = {
 | 
			
		||||
    ITransformERC20Feature: ITransformERC20Feature as ContractArtifact,
 | 
			
		||||
    IUniswapFeature: IUniswapFeature as ContractArtifact,
 | 
			
		||||
    IUniswapV3Feature: IUniswapV3Feature as ContractArtifact,
 | 
			
		||||
    LibERC721Order: LibERC721Order as ContractArtifact,
 | 
			
		||||
    LibNativeOrder: LibNativeOrder as ContractArtifact,
 | 
			
		||||
    LibSignature: LibSignature as ContractArtifact,
 | 
			
		||||
    MultiplexFeature: MultiplexFeature as ContractArtifact,
 | 
			
		||||
@@ -244,6 +262,7 @@ export const artifacts = {
 | 
			
		||||
    NativeOrdersSettlement: NativeOrdersSettlement as ContractArtifact,
 | 
			
		||||
    FixinCommon: FixinCommon as ContractArtifact,
 | 
			
		||||
    FixinEIP712: FixinEIP712 as ContractArtifact,
 | 
			
		||||
    FixinERC721Spender: FixinERC721Spender as ContractArtifact,
 | 
			
		||||
    FixinProtocolFees: FixinProtocolFees as ContractArtifact,
 | 
			
		||||
    FixinReentrancyGuard: FixinReentrancyGuard as ContractArtifact,
 | 
			
		||||
    FixinTokenSpender: FixinTokenSpender as ContractArtifact,
 | 
			
		||||
@@ -253,6 +272,7 @@ export const artifacts = {
 | 
			
		||||
    InitialMigration: InitialMigration as ContractArtifact,
 | 
			
		||||
    LibBootstrap: LibBootstrap as ContractArtifact,
 | 
			
		||||
    LibMigrate: LibMigrate as ContractArtifact,
 | 
			
		||||
    LibERC721OrdersStorage: LibERC721OrdersStorage as ContractArtifact,
 | 
			
		||||
    LibMetaTransactionsStorage: LibMetaTransactionsStorage as ContractArtifact,
 | 
			
		||||
    LibNativeOrdersStorage: LibNativeOrdersStorage as ContractArtifact,
 | 
			
		||||
    LibOtcOrdersStorage: LibOtcOrdersStorage as ContractArtifact,
 | 
			
		||||
@@ -298,8 +318,12 @@ export const artifacts = {
 | 
			
		||||
    MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
 | 
			
		||||
    MixinUniswapV3: MixinUniswapV3 as ContractArtifact,
 | 
			
		||||
    MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
 | 
			
		||||
    IERC721OrderCallback: IERC721OrderCallback as ContractArtifact,
 | 
			
		||||
    IERC721Token: IERC721Token as ContractArtifact,
 | 
			
		||||
    IFeeRecipient: IFeeRecipient as ContractArtifact,
 | 
			
		||||
    ILiquidityProvider: ILiquidityProvider as ContractArtifact,
 | 
			
		||||
    IMooniswapPool: IMooniswapPool as ContractArtifact,
 | 
			
		||||
    IPropertyValidator: IPropertyValidator as ContractArtifact,
 | 
			
		||||
    IUniswapV2Pair: IUniswapV2Pair as ContractArtifact,
 | 
			
		||||
    IUniswapV3Pool: IUniswapV3Pool as ContractArtifact,
 | 
			
		||||
    IERC20Bridge: IERC20Bridge as ContractArtifact,
 | 
			
		||||
@@ -307,9 +331,10 @@ export const artifacts = {
 | 
			
		||||
    ITestSimpleFunctionRegistryFeature: ITestSimpleFunctionRegistryFeature as ContractArtifact,
 | 
			
		||||
    TestBridge: TestBridge as ContractArtifact,
 | 
			
		||||
    TestCallTarget: TestCallTarget as ContractArtifact,
 | 
			
		||||
    TestCurve: TestCurve as ContractArtifact,
 | 
			
		||||
    TestDelegateCaller: TestDelegateCaller as ContractArtifact,
 | 
			
		||||
    TestERC721OrderPresigner: TestERC721OrderPresigner as ContractArtifact,
 | 
			
		||||
    TestFeeCollectorController: TestFeeCollectorController as ContractArtifact,
 | 
			
		||||
    TestFeeRecipient: TestFeeRecipient as ContractArtifact,
 | 
			
		||||
    TestFillQuoteTransformerBridge: TestFillQuoteTransformerBridge as ContractArtifact,
 | 
			
		||||
    TestFillQuoteTransformerExchange: TestFillQuoteTransformerExchange as ContractArtifact,
 | 
			
		||||
    TestFillQuoteTransformerHost: TestFillQuoteTransformerHost as ContractArtifact,
 | 
			
		||||
@@ -319,33 +344,36 @@ export const artifacts = {
 | 
			
		||||
    TestInitialMigration: TestInitialMigration as ContractArtifact,
 | 
			
		||||
    TestLibNativeOrder: TestLibNativeOrder as ContractArtifact,
 | 
			
		||||
    TestLibSignature: TestLibSignature as ContractArtifact,
 | 
			
		||||
    TestLiquidityProvider: TestLiquidityProvider as ContractArtifact,
 | 
			
		||||
    TestMetaTransactionsNativeOrdersFeature: TestMetaTransactionsNativeOrdersFeature as ContractArtifact,
 | 
			
		||||
    TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact,
 | 
			
		||||
    TestMigrator: TestMigrator as ContractArtifact,
 | 
			
		||||
    TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact,
 | 
			
		||||
    TestMintableERC20Token: TestMintableERC20Token as ContractArtifact,
 | 
			
		||||
    TestMooniswap: TestMooniswap as ContractArtifact,
 | 
			
		||||
    TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact,
 | 
			
		||||
    TestNoEthRecipient: TestNoEthRecipient as ContractArtifact,
 | 
			
		||||
    TestOrderSignerRegistryWithContractWallet: TestOrderSignerRegistryWithContractWallet as ContractArtifact,
 | 
			
		||||
    TestPermissionlessTransformerDeployerSuicidal: TestPermissionlessTransformerDeployerSuicidal as ContractArtifact,
 | 
			
		||||
    TestPermissionlessTransformerDeployerTransformer: TestPermissionlessTransformerDeployerTransformer as ContractArtifact,
 | 
			
		||||
    TestPropertyValidator: TestPropertyValidator as ContractArtifact,
 | 
			
		||||
    TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact,
 | 
			
		||||
    TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact,
 | 
			
		||||
    TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 as ContractArtifact,
 | 
			
		||||
    TestStaking: TestStaking as ContractArtifact,
 | 
			
		||||
    TestTokenSpenderERC20Token: TestTokenSpenderERC20Token as ContractArtifact,
 | 
			
		||||
    TestTransformERC20: TestTransformERC20 as ContractArtifact,
 | 
			
		||||
    TestTransformerBase: TestTransformerBase as ContractArtifact,
 | 
			
		||||
    TestTransformerDeployerTransformer: TestTransformerDeployerTransformer as ContractArtifact,
 | 
			
		||||
    TestTransformerHost: TestTransformerHost as ContractArtifact,
 | 
			
		||||
    TestUniswapV3Feature: TestUniswapV3Feature as ContractArtifact,
 | 
			
		||||
    TestWethTransformerHost: TestWethTransformerHost as ContractArtifact,
 | 
			
		||||
    TestZeroExFeature: TestZeroExFeature as ContractArtifact,
 | 
			
		||||
    TestCurve: TestCurve as ContractArtifact,
 | 
			
		||||
    TestLiquidityProvider: TestLiquidityProvider as ContractArtifact,
 | 
			
		||||
    TestMooniswap: TestMooniswap as ContractArtifact,
 | 
			
		||||
    TestUniswapV2Factory: TestUniswapV2Factory as ContractArtifact,
 | 
			
		||||
    TestUniswapV2Pool: TestUniswapV2Pool as ContractArtifact,
 | 
			
		||||
    TestUniswapV3Factory: TestUniswapV3Factory as ContractArtifact,
 | 
			
		||||
    TestUniswapV3Feature: TestUniswapV3Feature as ContractArtifact,
 | 
			
		||||
    TestUniswapV3Pool: TestUniswapV3Pool as ContractArtifact,
 | 
			
		||||
    TestMintableERC20Token: TestMintableERC20Token as ContractArtifact,
 | 
			
		||||
    TestMintableERC721Token: TestMintableERC721Token as ContractArtifact,
 | 
			
		||||
    TestTokenSpenderERC20Token: TestTokenSpenderERC20Token as ContractArtifact,
 | 
			
		||||
    TestWeth: TestWeth as ContractArtifact,
 | 
			
		||||
    TestWethTransformerHost: TestWethTransformerHost as ContractArtifact,
 | 
			
		||||
    TestZeroExFeature: TestZeroExFeature as ContractArtifact,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1756
									
								
								contracts/zero-ex/test/features/erc721_orders_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1756
									
								
								contracts/zero-ex/test/features/erc721_orders_test.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										22
									
								
								contracts/zero-ex/test/utils/erc721_orders.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								contracts/zero-ex/test/utils/erc721_orders.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { constants, getRandomInteger, randomAddress } from '@0x/contracts-test-utils';
 | 
			
		||||
import { ERC721Order } from '@0x/protocol-utils';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate a random ERC721 Order
 | 
			
		||||
 */
 | 
			
		||||
export function getRandomERC721Order(fields: Partial<ERC721Order> = {}): ERC721Order {
 | 
			
		||||
    return new ERC721Order({
 | 
			
		||||
        erc20Token: randomAddress(),
 | 
			
		||||
        erc20TokenAmount: getRandomInteger('1e18', '10e18'),
 | 
			
		||||
        erc721Token: randomAddress(),
 | 
			
		||||
        erc721TokenId: getRandomInteger(0, constants.MAX_UINT256),
 | 
			
		||||
        maker: randomAddress(),
 | 
			
		||||
        taker: randomAddress(),
 | 
			
		||||
        erc721TokenProperties: [],
 | 
			
		||||
        fees: [],
 | 
			
		||||
        nonce: getRandomInteger(0, constants.MAX_UINT256),
 | 
			
		||||
        expiry: new BigNumber(Math.floor(Date.now() / 1000 + 60)),
 | 
			
		||||
        ...fields,
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
@@ -9,11 +9,13 @@ export * from '../test/generated-wrappers/bootstrap_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/bridge_protocols';
 | 
			
		||||
export * from '../test/generated-wrappers/curve_liquidity_provider';
 | 
			
		||||
export * from '../test/generated-wrappers/erc721_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/fee_collector';
 | 
			
		||||
export * from '../test/generated-wrappers/fee_collector_controller';
 | 
			
		||||
export * from '../test/generated-wrappers/fill_quote_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/fixin_common';
 | 
			
		||||
export * from '../test/generated-wrappers/fixin_e_i_p712';
 | 
			
		||||
export * from '../test/generated-wrappers/fixin_erc721_spender';
 | 
			
		||||
export * from '../test/generated-wrappers/fixin_protocol_fees';
 | 
			
		||||
export * from '../test/generated-wrappers/fixin_reentrancy_guard';
 | 
			
		||||
export * from '../test/generated-wrappers/fixin_token_spender';
 | 
			
		||||
@@ -25,7 +27,11 @@ export * from '../test/generated-wrappers/i_bootstrap_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/i_erc20_bridge';
 | 
			
		||||
export * from '../test/generated-wrappers/i_erc20_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/i_erc721_order_callback';
 | 
			
		||||
export * from '../test/generated-wrappers/i_erc721_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_erc721_token';
 | 
			
		||||
export * from '../test/generated-wrappers/i_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_fee_recipient';
 | 
			
		||||
export * from '../test/generated-wrappers/i_flash_wallet';
 | 
			
		||||
export * from '../test/generated-wrappers/i_fund_recovery_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_liquidity_provider';
 | 
			
		||||
@@ -39,6 +45,7 @@ export * from '../test/generated-wrappers/i_native_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_otc_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_ownable_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_pancake_swap_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_property_validator';
 | 
			
		||||
export * from '../test/generated-wrappers/i_simple_function_registry_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/i_staking';
 | 
			
		||||
export * from '../test/generated-wrappers/i_test_simple_function_registry_feature';
 | 
			
		||||
@@ -53,6 +60,9 @@ export * from '../test/generated-wrappers/initial_migration';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_bootstrap';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_common_rich_errors';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_erc20_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_erc721_order';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_erc721_orders_rich_errors';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_erc721_orders_storage';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_fee_collector';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_liquidity_provider_rich_errors';
 | 
			
		||||
export * from '../test/generated-wrappers/lib_meta_transactions_rich_errors';
 | 
			
		||||
@@ -127,7 +137,9 @@ export * from '../test/generated-wrappers/test_bridge';
 | 
			
		||||
export * from '../test/generated-wrappers/test_call_target';
 | 
			
		||||
export * from '../test/generated-wrappers/test_curve';
 | 
			
		||||
export * from '../test/generated-wrappers/test_delegate_caller';
 | 
			
		||||
export * from '../test/generated-wrappers/test_erc721_order_presigner';
 | 
			
		||||
export * from '../test/generated-wrappers/test_fee_collector_controller';
 | 
			
		||||
export * from '../test/generated-wrappers/test_fee_recipient';
 | 
			
		||||
export * from '../test/generated-wrappers/test_fill_quote_transformer_bridge';
 | 
			
		||||
export * from '../test/generated-wrappers/test_fill_quote_transformer_exchange';
 | 
			
		||||
export * from '../test/generated-wrappers/test_fill_quote_transformer_host';
 | 
			
		||||
@@ -143,12 +155,14 @@ export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20
 | 
			
		||||
export * from '../test/generated-wrappers/test_migrator';
 | 
			
		||||
export * from '../test/generated-wrappers/test_mint_token_erc20_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/test_mintable_erc20_token';
 | 
			
		||||
export * from '../test/generated-wrappers/test_mintable_erc721_token';
 | 
			
		||||
export * from '../test/generated-wrappers/test_mooniswap';
 | 
			
		||||
export * from '../test/generated-wrappers/test_native_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/test_no_eth_recipient';
 | 
			
		||||
export * from '../test/generated-wrappers/test_order_signer_registry_with_contract_wallet';
 | 
			
		||||
export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_suicidal';
 | 
			
		||||
export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/test_property_validator';
 | 
			
		||||
export * from '../test/generated-wrappers/test_rfq_origin_registration';
 | 
			
		||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1';
 | 
			
		||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2';
 | 
			
		||||
 
 | 
			
		||||
@@ -42,11 +42,13 @@
 | 
			
		||||
        "test/generated-artifacts/BridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/BridgeProtocols.json",
 | 
			
		||||
        "test/generated-artifacts/CurveLiquidityProvider.json",
 | 
			
		||||
        "test/generated-artifacts/ERC721OrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/FeeCollector.json",
 | 
			
		||||
        "test/generated-artifacts/FeeCollectorController.json",
 | 
			
		||||
        "test/generated-artifacts/FillQuoteTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/FixinCommon.json",
 | 
			
		||||
        "test/generated-artifacts/FixinEIP712.json",
 | 
			
		||||
        "test/generated-artifacts/FixinERC721Spender.json",
 | 
			
		||||
        "test/generated-artifacts/FixinProtocolFees.json",
 | 
			
		||||
        "test/generated-artifacts/FixinReentrancyGuard.json",
 | 
			
		||||
        "test/generated-artifacts/FixinTokenSpender.json",
 | 
			
		||||
@@ -58,7 +60,11 @@
 | 
			
		||||
        "test/generated-artifacts/IBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/IERC20Bridge.json",
 | 
			
		||||
        "test/generated-artifacts/IERC20Transformer.json",
 | 
			
		||||
        "test/generated-artifacts/IERC721OrderCallback.json",
 | 
			
		||||
        "test/generated-artifacts/IERC721OrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/IERC721Token.json",
 | 
			
		||||
        "test/generated-artifacts/IFeature.json",
 | 
			
		||||
        "test/generated-artifacts/IFeeRecipient.json",
 | 
			
		||||
        "test/generated-artifacts/IFlashWallet.json",
 | 
			
		||||
        "test/generated-artifacts/IFundRecoveryFeature.json",
 | 
			
		||||
        "test/generated-artifacts/ILiquidityProvider.json",
 | 
			
		||||
@@ -72,6 +78,7 @@
 | 
			
		||||
        "test/generated-artifacts/IOtcOrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/IOwnableFeature.json",
 | 
			
		||||
        "test/generated-artifacts/IPancakeSwapFeature.json",
 | 
			
		||||
        "test/generated-artifacts/IPropertyValidator.json",
 | 
			
		||||
        "test/generated-artifacts/ISimpleFunctionRegistryFeature.json",
 | 
			
		||||
        "test/generated-artifacts/IStaking.json",
 | 
			
		||||
        "test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
 | 
			
		||||
@@ -86,6 +93,9 @@
 | 
			
		||||
        "test/generated-artifacts/LibBootstrap.json",
 | 
			
		||||
        "test/generated-artifacts/LibCommonRichErrors.json",
 | 
			
		||||
        "test/generated-artifacts/LibERC20Transformer.json",
 | 
			
		||||
        "test/generated-artifacts/LibERC721Order.json",
 | 
			
		||||
        "test/generated-artifacts/LibERC721OrdersRichErrors.json",
 | 
			
		||||
        "test/generated-artifacts/LibERC721OrdersStorage.json",
 | 
			
		||||
        "test/generated-artifacts/LibFeeCollector.json",
 | 
			
		||||
        "test/generated-artifacts/LibLiquidityProviderRichErrors.json",
 | 
			
		||||
        "test/generated-artifacts/LibMetaTransactionsRichErrors.json",
 | 
			
		||||
@@ -160,7 +170,9 @@
 | 
			
		||||
        "test/generated-artifacts/TestCallTarget.json",
 | 
			
		||||
        "test/generated-artifacts/TestCurve.json",
 | 
			
		||||
        "test/generated-artifacts/TestDelegateCaller.json",
 | 
			
		||||
        "test/generated-artifacts/TestERC721OrderPresigner.json",
 | 
			
		||||
        "test/generated-artifacts/TestFeeCollectorController.json",
 | 
			
		||||
        "test/generated-artifacts/TestFeeRecipient.json",
 | 
			
		||||
        "test/generated-artifacts/TestFillQuoteTransformerBridge.json",
 | 
			
		||||
        "test/generated-artifacts/TestFillQuoteTransformerExchange.json",
 | 
			
		||||
        "test/generated-artifacts/TestFillQuoteTransformerHost.json",
 | 
			
		||||
@@ -176,12 +188,14 @@
 | 
			
		||||
        "test/generated-artifacts/TestMigrator.json",
 | 
			
		||||
        "test/generated-artifacts/TestMintTokenERC20Transformer.json",
 | 
			
		||||
        "test/generated-artifacts/TestMintableERC20Token.json",
 | 
			
		||||
        "test/generated-artifacts/TestMintableERC721Token.json",
 | 
			
		||||
        "test/generated-artifacts/TestMooniswap.json",
 | 
			
		||||
        "test/generated-artifacts/TestNativeOrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/TestNoEthRecipient.json",
 | 
			
		||||
        "test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json",
 | 
			
		||||
        "test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json",
 | 
			
		||||
        "test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/TestPropertyValidator.json",
 | 
			
		||||
        "test/generated-artifacts/TestRfqOriginRegistration.json",
 | 
			
		||||
        "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json",
 | 
			
		||||
        "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json",
 | 
			
		||||
 
 | 
			
		||||
@@ -74,8 +74,19 @@ export function getExchangeProxyEIP712Hash(structHash: string, chainId?: number,
 | 
			
		||||
/**
 | 
			
		||||
 * Compute the type hash of an EIP712 struct given its ABI.
 | 
			
		||||
 */
 | 
			
		||||
export function getTypeHash(structName: string, abi: EIP712_STRUCT_ABI): string {
 | 
			
		||||
    return hexUtils.hash(
 | 
			
		||||
        hexUtils.toHex(Buffer.from([`${structName}(`, abi.map(a => `${a.type} ${a.name}`).join(','), ')'].join(''))),
 | 
			
		||||
    );
 | 
			
		||||
export function getTypeHash(
 | 
			
		||||
    primaryStructName: string,
 | 
			
		||||
    primaryStructAbi: EIP712_STRUCT_ABI,
 | 
			
		||||
    referencedStructs: { [structName: string]: EIP712_STRUCT_ABI } = {},
 | 
			
		||||
): string {
 | 
			
		||||
    const primaryStructType = encodeType(primaryStructName, primaryStructAbi);
 | 
			
		||||
    // Referenced structs are sorted lexicographically
 | 
			
		||||
    const referencedStructTypes = Object.entries(referencedStructs)
 | 
			
		||||
        .sort(([nameA], [nameB]) => nameA.localeCompare(nameB))
 | 
			
		||||
        .map(([name, abi]) => encodeType(name, abi));
 | 
			
		||||
    return hexUtils.hash(hexUtils.toHex(Buffer.from(primaryStructType + referencedStructTypes.join(''))));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function encodeType(structName: string, abi: EIP712_STRUCT_ABI): string {
 | 
			
		||||
    return [`${structName}(`, abi.map(a => `${a.type} ${a.name}`).join(','), ')'].join('');
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										260
									
								
								packages/protocol-utils/src/erc721_orders.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								packages/protocol-utils/src/erc721_orders.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
 | 
			
		||||
import { SupportedProvider } from '@0x/subproviders';
 | 
			
		||||
import { EIP712TypedData } from '@0x/types';
 | 
			
		||||
import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { ZERO } from './constants';
 | 
			
		||||
import {
 | 
			
		||||
    createExchangeProxyEIP712Domain,
 | 
			
		||||
    EIP712_DOMAIN_PARAMETERS,
 | 
			
		||||
    getExchangeProxyEIP712Hash,
 | 
			
		||||
    getTypeHash,
 | 
			
		||||
} from './eip712_utils';
 | 
			
		||||
import {
 | 
			
		||||
    eip712SignHashWithKey,
 | 
			
		||||
    eip712SignTypedDataWithProviderAsync,
 | 
			
		||||
    ethSignHashWithKey,
 | 
			
		||||
    ethSignHashWithProviderAsync,
 | 
			
		||||
    Signature,
 | 
			
		||||
    SignatureType,
 | 
			
		||||
} from './signature_utils';
 | 
			
		||||
 | 
			
		||||
export class ERC721Order {
 | 
			
		||||
    public static readonly STRUCT_NAME = 'ERC721Order';
 | 
			
		||||
    public static readonly STRUCT_ABI = [
 | 
			
		||||
        { type: 'uint8', name: 'direction' },
 | 
			
		||||
        { type: 'address', name: 'erc20Token' },
 | 
			
		||||
        { type: 'uint256', name: 'erc20TokenAmount' },
 | 
			
		||||
        { type: 'address', name: 'erc721Token' },
 | 
			
		||||
        { type: 'uint256', name: 'erc721TokenId' },
 | 
			
		||||
        { type: 'Property[]', name: 'erc721TokenProperties' },
 | 
			
		||||
        { type: 'Fee[]', name: 'fees' },
 | 
			
		||||
        { type: 'address', name: 'maker' },
 | 
			
		||||
        { type: 'address', name: 'taker' },
 | 
			
		||||
        { type: 'uint256', name: 'expiry' },
 | 
			
		||||
        { type: 'uint256', name: 'nonce' },
 | 
			
		||||
    ];
 | 
			
		||||
    public static readonly REFERENCED_STRUCT_ABIS = {
 | 
			
		||||
        ['Fee']: [
 | 
			
		||||
            { type: 'address', name: 'recipient' },
 | 
			
		||||
            { type: 'uint256', name: 'amount' },
 | 
			
		||||
            { type: 'bytes', name: 'feeData' },
 | 
			
		||||
        ],
 | 
			
		||||
        ['Property']: [
 | 
			
		||||
            { type: 'address', name: 'propertyValidator' },
 | 
			
		||||
            { type: 'bytes', name: 'propertyData' },
 | 
			
		||||
        ],
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    public static readonly TYPE_HASH = getTypeHash(
 | 
			
		||||
        ERC721Order.STRUCT_NAME,
 | 
			
		||||
        ERC721Order.STRUCT_ABI,
 | 
			
		||||
        ERC721Order.REFERENCED_STRUCT_ABIS,
 | 
			
		||||
    );
 | 
			
		||||
    public static readonly FEE_TYPE_HASH = getTypeHash('Fee', ERC721Order.REFERENCED_STRUCT_ABIS.Fee);
 | 
			
		||||
    public static readonly PROPERTY_TYPE_HASH = getTypeHash('Property', ERC721Order.REFERENCED_STRUCT_ABIS.Property);
 | 
			
		||||
 | 
			
		||||
    public direction: ERC721Order.TradeDirection;
 | 
			
		||||
    public erc20Token: string;
 | 
			
		||||
    public erc20TokenAmount: BigNumber;
 | 
			
		||||
    public erc721Token: string;
 | 
			
		||||
    public erc721TokenId: BigNumber;
 | 
			
		||||
    public erc721TokenProperties: ERC721Order.Property[];
 | 
			
		||||
    public fees: ERC721Order.Fee[];
 | 
			
		||||
    public maker: string;
 | 
			
		||||
    public taker: string;
 | 
			
		||||
    public expiry: BigNumber;
 | 
			
		||||
    public nonce: BigNumber;
 | 
			
		||||
    public chainId: number;
 | 
			
		||||
    public verifyingContract: string;
 | 
			
		||||
 | 
			
		||||
    constructor(fields: Partial<ERC721OrderFields> = {}) {
 | 
			
		||||
        const _fields = { ...ERC721_ORDER_DEFAULT_VALUES, ...fields };
 | 
			
		||||
        this.direction = _fields.direction;
 | 
			
		||||
        this.erc20Token = _fields.erc20Token;
 | 
			
		||||
        this.erc20TokenAmount = _fields.erc20TokenAmount;
 | 
			
		||||
        this.erc721Token = _fields.erc721Token;
 | 
			
		||||
        this.erc721TokenId = _fields.erc721TokenId;
 | 
			
		||||
        this.erc721TokenProperties = _fields.erc721TokenProperties;
 | 
			
		||||
        this.fees = _fields.fees;
 | 
			
		||||
        this.maker = _fields.maker;
 | 
			
		||||
        this.taker = _fields.taker;
 | 
			
		||||
        this.expiry = _fields.expiry;
 | 
			
		||||
        this.nonce = _fields.nonce;
 | 
			
		||||
        this.chainId = _fields.chainId;
 | 
			
		||||
        this.verifyingContract = _fields.verifyingContract;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public clone(fields: Partial<ERC721OrderFields> = {}): ERC721Order {
 | 
			
		||||
        return new ERC721Order({
 | 
			
		||||
            direction: this.direction,
 | 
			
		||||
            erc20Token: this.erc20Token,
 | 
			
		||||
            erc20TokenAmount: this.erc20TokenAmount,
 | 
			
		||||
            erc721Token: this.erc721Token,
 | 
			
		||||
            erc721TokenId: this.erc721TokenId,
 | 
			
		||||
            erc721TokenProperties: this.erc721TokenProperties,
 | 
			
		||||
            fees: this.fees,
 | 
			
		||||
            maker: this.maker,
 | 
			
		||||
            taker: this.taker,
 | 
			
		||||
            expiry: this.expiry,
 | 
			
		||||
            nonce: this.nonce,
 | 
			
		||||
            chainId: this.chainId,
 | 
			
		||||
            verifyingContract: this.verifyingContract,
 | 
			
		||||
            ...fields,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getStructHash(): string {
 | 
			
		||||
        const propertiesHash = hexUtils.hash(
 | 
			
		||||
            hexUtils.concat(
 | 
			
		||||
                ...this.erc721TokenProperties.map(property =>
 | 
			
		||||
                    hexUtils.hash(
 | 
			
		||||
                        hexUtils.concat(
 | 
			
		||||
                            hexUtils.leftPad(ERC721Order.PROPERTY_TYPE_HASH),
 | 
			
		||||
                            hexUtils.leftPad(property.propertyValidator),
 | 
			
		||||
                            hexUtils.hash(property.propertyData),
 | 
			
		||||
                        ),
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
        const feesHash = hexUtils.hash(
 | 
			
		||||
            hexUtils.concat(
 | 
			
		||||
                ...this.fees.map(fee =>
 | 
			
		||||
                    hexUtils.hash(
 | 
			
		||||
                        hexUtils.concat(
 | 
			
		||||
                            hexUtils.leftPad(ERC721Order.FEE_TYPE_HASH),
 | 
			
		||||
                            hexUtils.leftPad(fee.recipient),
 | 
			
		||||
                            hexUtils.leftPad(fee.amount),
 | 
			
		||||
                            hexUtils.hash(fee.feeData),
 | 
			
		||||
                        ),
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
        return hexUtils.hash(
 | 
			
		||||
            hexUtils.concat(
 | 
			
		||||
                hexUtils.leftPad(ERC721Order.TYPE_HASH),
 | 
			
		||||
                hexUtils.leftPad(this.direction),
 | 
			
		||||
                hexUtils.leftPad(this.erc20Token),
 | 
			
		||||
                hexUtils.leftPad(this.erc20TokenAmount),
 | 
			
		||||
                hexUtils.leftPad(this.erc721Token),
 | 
			
		||||
                hexUtils.leftPad(this.erc721TokenId),
 | 
			
		||||
                propertiesHash,
 | 
			
		||||
                feesHash,
 | 
			
		||||
                hexUtils.leftPad(this.maker),
 | 
			
		||||
                hexUtils.leftPad(this.taker),
 | 
			
		||||
                hexUtils.leftPad(this.expiry),
 | 
			
		||||
                hexUtils.leftPad(this.nonce),
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getEIP712TypedData(): EIP712TypedData {
 | 
			
		||||
        return {
 | 
			
		||||
            types: {
 | 
			
		||||
                EIP712Domain: EIP712_DOMAIN_PARAMETERS,
 | 
			
		||||
                [ERC721Order.STRUCT_NAME]: ERC721Order.STRUCT_ABI,
 | 
			
		||||
                ...ERC721Order.REFERENCED_STRUCT_ABIS,
 | 
			
		||||
            },
 | 
			
		||||
            domain: createExchangeProxyEIP712Domain(this.chainId, this.verifyingContract) as any,
 | 
			
		||||
            primaryType: ERC721Order.STRUCT_NAME,
 | 
			
		||||
            message: {
 | 
			
		||||
                direction: this.direction,
 | 
			
		||||
                erc20Token: this.erc20Token,
 | 
			
		||||
                erc20TokenAmount: this.erc20TokenAmount.toString(10),
 | 
			
		||||
                erc721Token: this.erc721Token,
 | 
			
		||||
                erc721TokenId: this.erc721TokenId.toString(10),
 | 
			
		||||
                erc721TokenProperties: this.erc721TokenProperties as any,
 | 
			
		||||
                fees: this.fees.map(fee => ({
 | 
			
		||||
                    recipient: fee.recipient,
 | 
			
		||||
                    amount: fee.amount.toString(10),
 | 
			
		||||
                    feeData: fee.feeData,
 | 
			
		||||
                })) as any,
 | 
			
		||||
                maker: this.maker,
 | 
			
		||||
                taker: this.taker,
 | 
			
		||||
                expiry: this.expiry.toString(10),
 | 
			
		||||
                nonce: this.nonce.toString(10),
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public willExpire(secondsFromNow: number = 0): boolean {
 | 
			
		||||
        const millisecondsInSecond = 1000;
 | 
			
		||||
        const currentUnixTimestampSec = new BigNumber(Date.now() / millisecondsInSecond).integerValue();
 | 
			
		||||
        return this.expiry.isLessThan(currentUnixTimestampSec.plus(secondsFromNow));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getHash(): string {
 | 
			
		||||
        return getExchangeProxyEIP712Hash(this.getStructHash(), this.chainId, this.verifyingContract);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async getSignatureWithProviderAsync(
 | 
			
		||||
        provider: SupportedProvider,
 | 
			
		||||
        type: SignatureType = SignatureType.EthSign,
 | 
			
		||||
        signer: string = this.maker,
 | 
			
		||||
    ): Promise<Signature> {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case SignatureType.EIP712:
 | 
			
		||||
                return eip712SignTypedDataWithProviderAsync(this.getEIP712TypedData(), signer, provider);
 | 
			
		||||
            case SignatureType.EthSign:
 | 
			
		||||
                return ethSignHashWithProviderAsync(this.getHash(), signer, provider);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new Error(`Cannot sign with signature type: ${type}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getSignatureWithKey(key: string, type: SignatureType = SignatureType.EthSign): Signature {
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case SignatureType.EIP712:
 | 
			
		||||
                return eip712SignHashWithKey(this.getHash(), key);
 | 
			
		||||
            case SignatureType.EthSign:
 | 
			
		||||
                return ethSignHashWithKey(this.getHash(), key);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new Error(`Cannot sign with signature type: ${type}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export namespace ERC721Order {
 | 
			
		||||
    export interface Property {
 | 
			
		||||
        propertyValidator: string;
 | 
			
		||||
        propertyData: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export interface Fee {
 | 
			
		||||
        recipient: string;
 | 
			
		||||
        amount: BigNumber;
 | 
			
		||||
        feeData: string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export enum TradeDirection {
 | 
			
		||||
        Sell721 = 0,
 | 
			
		||||
        Buy721 = 1,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export enum OrderStatus {
 | 
			
		||||
        Invalid = 0,
 | 
			
		||||
        Fillable = 1,
 | 
			
		||||
        Unfillable = 2,
 | 
			
		||||
        Expired = 3,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ERC721_ORDER_DEFAULT_VALUES = {
 | 
			
		||||
    direction: ERC721Order.TradeDirection.Sell721,
 | 
			
		||||
    erc20Token: NULL_ADDRESS,
 | 
			
		||||
    erc20TokenAmount: ZERO,
 | 
			
		||||
    erc721Token: NULL_ADDRESS,
 | 
			
		||||
    erc721TokenId: ZERO,
 | 
			
		||||
    erc721TokenProperties: [] as ERC721Order.Property[],
 | 
			
		||||
    fees: [] as ERC721Order.Fee[],
 | 
			
		||||
    maker: NULL_ADDRESS,
 | 
			
		||||
    taker: NULL_ADDRESS,
 | 
			
		||||
    expiry: ZERO,
 | 
			
		||||
    nonce: ZERO,
 | 
			
		||||
    chainId: 1,
 | 
			
		||||
    verifyingContract: getContractAddressesForChainOrThrow(1).exchangeProxy,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type ERC721OrderFields = typeof ERC721_ORDER_DEFAULT_VALUES;
 | 
			
		||||
@@ -10,3 +10,4 @@ export * from './transformer_utils';
 | 
			
		||||
export * from './constants';
 | 
			
		||||
export * from './vip_utils';
 | 
			
		||||
export * from './treasury_votes';
 | 
			
		||||
export * from './erc721_orders';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										132
									
								
								packages/protocol-utils/src/revert-errors/erc721_orders.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								packages/protocol-utils/src/revert-errors/erc721_orders.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
// tslint:disable: max-classes-per-file
 | 
			
		||||
import { Numberish, RevertError } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { ERC721Order } from '../erc721_orders';
 | 
			
		||||
 | 
			
		||||
export class OverspentEthError extends RevertError {
 | 
			
		||||
    constructor(ethSpent?: Numberish, msgValue?: Numberish) {
 | 
			
		||||
        super('OverspentEthError', 'OverspentEthError(uint256 ethSpent, uint256 msgValue)', {
 | 
			
		||||
            ethSpent,
 | 
			
		||||
            msgValue,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class InsufficientEthError extends RevertError {
 | 
			
		||||
    constructor(ethAvailable?: Numberish, orderAmount?: Numberish) {
 | 
			
		||||
        super('InsufficientEthError', 'InsufficientEthError(uint256 ethAvailable, uint256 orderAmount)', {
 | 
			
		||||
            ethAvailable,
 | 
			
		||||
            orderAmount,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ERC721TokenMismatchError extends RevertError {
 | 
			
		||||
    constructor(token1?: string, token2?: string) {
 | 
			
		||||
        super('ERC721TokenMismatchError', 'ERC721TokenMismatchError(address token1, address token2)', {
 | 
			
		||||
            token1,
 | 
			
		||||
            token2,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ERC20TokenMismatchError extends RevertError {
 | 
			
		||||
    constructor(token1?: string, token2?: string) {
 | 
			
		||||
        super('ERC20TokenMismatchError', 'ERC20TokenMismatchError(address token1, address token2)', {
 | 
			
		||||
            token1,
 | 
			
		||||
            token2,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class NegativeSpreadError extends RevertError {
 | 
			
		||||
    constructor(sellOrderAmount?: Numberish, buyOrderAmount?: Numberish) {
 | 
			
		||||
        super('NegativeSpreadError', 'NegativeSpreadError(uint256 sellOrderAmount, uint256 buyOrderAmount)', {
 | 
			
		||||
            sellOrderAmount,
 | 
			
		||||
            buyOrderAmount,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SellOrderFeesExceedSpreadError extends RevertError {
 | 
			
		||||
    constructor(sellOrderFees?: Numberish, spread?: Numberish) {
 | 
			
		||||
        super(
 | 
			
		||||
            'SellOrderFeesExceedSpreadError',
 | 
			
		||||
            'SellOrderFeesExceedSpreadError(uint256 sellOrderFees, uint256 spread)',
 | 
			
		||||
            {
 | 
			
		||||
                sellOrderFees,
 | 
			
		||||
                spread,
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class OnlyTakerError extends RevertError {
 | 
			
		||||
    constructor(sender?: string, taker?: string) {
 | 
			
		||||
        super('OnlyTakerError', 'OnlyTakerError(address sender, address taker)', {
 | 
			
		||||
            sender,
 | 
			
		||||
            taker,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { InvalidSignerError } from './native_orders';
 | 
			
		||||
 | 
			
		||||
export class OrderNotFillableError extends RevertError {
 | 
			
		||||
    constructor(maker?: string, nonce?: Numberish, orderStatus?: ERC721Order.OrderStatus) {
 | 
			
		||||
        super('OrderNotFillableError', 'OrderNotFillableError(address maker, uint256 nonce, uint8 orderStatus)', {
 | 
			
		||||
            maker,
 | 
			
		||||
            nonce,
 | 
			
		||||
            orderStatus,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ERC721TokenIdMismatchError extends RevertError {
 | 
			
		||||
    constructor(tokenId?: Numberish, orderTokenId?: Numberish) {
 | 
			
		||||
        super('ERC721TokenIdMismatchError', 'ERC721TokenIdMismatchError(uint256 tokenId, uint256 orderTokenId)', {
 | 
			
		||||
            tokenId,
 | 
			
		||||
            orderTokenId,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class PropertyValidationFailedError extends RevertError {
 | 
			
		||||
    constructor(
 | 
			
		||||
        propertyValidator?: string,
 | 
			
		||||
        erc721Token?: string,
 | 
			
		||||
        erc721TokenId?: Numberish,
 | 
			
		||||
        propertyData?: string,
 | 
			
		||||
        errorData?: string,
 | 
			
		||||
    ) {
 | 
			
		||||
        super(
 | 
			
		||||
            'PropertyValidationFailedError',
 | 
			
		||||
            'PropertyValidationFailedError(address propertyValidator, address erc721Token, uint256 erc721TokenId, bytes propertyData, bytes errorData)',
 | 
			
		||||
            {
 | 
			
		||||
                propertyValidator,
 | 
			
		||||
                erc721Token,
 | 
			
		||||
                erc721TokenId,
 | 
			
		||||
                propertyData,
 | 
			
		||||
                errorData,
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const types = [
 | 
			
		||||
    OverspentEthError,
 | 
			
		||||
    InsufficientEthError,
 | 
			
		||||
    ERC721TokenMismatchError,
 | 
			
		||||
    ERC20TokenMismatchError,
 | 
			
		||||
    NegativeSpreadError,
 | 
			
		||||
    SellOrderFeesExceedSpreadError,
 | 
			
		||||
    OnlyTakerError,
 | 
			
		||||
    OrderNotFillableError,
 | 
			
		||||
    ERC721TokenIdMismatchError,
 | 
			
		||||
    PropertyValidationFailedError,
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
// Register the types we've defined.
 | 
			
		||||
for (const type of types) {
 | 
			
		||||
    RevertError.registerType(type);
 | 
			
		||||
}
 | 
			
		||||
@@ -14,6 +14,7 @@ import {
 | 
			
		||||
} from './inherited';
 | 
			
		||||
import * as NativeOrders from './native_orders';
 | 
			
		||||
import * as Signatures from './signatures';
 | 
			
		||||
import * as ERC721Orders from './erc721_orders';
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
    Common,
 | 
			
		||||
@@ -28,4 +29,5 @@ export {
 | 
			
		||||
    LiquidityProvider,
 | 
			
		||||
    NativeOrders,
 | 
			
		||||
    Signatures,
 | 
			
		||||
    ERC721Orders,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ export enum SignatureType {
 | 
			
		||||
    Invalid = 1,
 | 
			
		||||
    EIP712 = 2,
 | 
			
		||||
    EthSign = 3,
 | 
			
		||||
    PreSigned = 4,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user