Compare commits
	
		
			26 Commits
		
	
	
		
			@0x/contra
			...
			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