You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This ZEIP introduces a new set of features to enable NFT orders on the 0x V4 protocol. NFT orders allows for trades of ERC-721 or ERC-1155 in exchange for ERC-20. We have optimized the implementation to reduce costs by up to 54% against other comparable protocols.
Type:
CORE
Motivation
Similar to previous versions of 0x protocol we want to support a thriving NFT ecosystem and offer traders the best experience.
Specification
Basics
Users can sign an off-chain order to indicate that they are interested in:
selling a particular NFT for some amount of ERC20 token (or ETH), or
buying a particular NFT for some amount of ERC20 token.
There are two Solidity order structs:
ERC721Order for buying/selling ERC721 assets
ERC1155Order for buying/selling ERC1155 assets.
ERC1155Order has one additional field compared to ERC721Order, used to specify the amount of the ERC1155 being bought or sold. This would be used for fungible ERC1155 assets.
The TradeDirection enum is used to indicate whether an order is a bid or an ask:
Upon discovering a listing, a trader, with the help of a dApp, will fill the ERC721 Order on-chain.
/// @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(
LibNFTOrder.ERC721Order _calldata_ sellOrder,
LibSignature.Signature _calldata_ signature,
bytes _calldata_ callbackData
)
externalpayable;
Collection/floor/property-based orders
In lieu of specifying a particular token ID, buy orders can specify a list of properties that an NFT asset must satisfy to be used to fill the order.
These properties are encoded using the following struct:
where propertyValidator implements the following function:
/// @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(
addresstokenAddress,
uint256tokenId,
bytescalldatapropertyData
)
externalview;
Fees
An order can specify fees to be paid out during settlement, denominated in the ERC20 token of the order. Both ERC721Order and ERC1155Order have a Fee[] fees field, where Fee is the following struct:
If the feeData length is greater than 0 then a fee callback will be called. The receiver must implement the IFeeRecipient interface.
interfaceIFeeRecipient {
/// @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 receiveFeeCallback(
addresstokenAddress,
uint256amount,
bytescalldatafeeData
)
externalreturns (bytes4success);
}
ETH/WETH handling
A sell order must use WETH instead of ETH, since we require the ERC20 transferFrom functionality to transfer WETH from the maker to the taker. Even so, the taker can choose to receive ETH when filling a WETH sell order by setting the unwrapNativeToken parameter to true in sellERC721 or sellERC1155.
A buy order can specify either ETH or WETH, i.e. the buyer can indicate whether they would like to receive ETH or WETH. A WETH sell order can be filled by a taker using ETH: the buyERC721 and buyERC1155 functions are payable and the msg.value can be used to fill a WETH sell order.
Pre-signing orders
Since smart contracts cannot sign orders in the traditional sense, they can instead “sign” orders by calling the preSignERC721Order or preSignERC1155Order functions.
Summary
This ZEIP introduces a new set of features to enable NFT orders on the 0x V4 protocol. NFT orders allows for trades of ERC-721 or ERC-1155 in exchange for ERC-20. We have optimized the implementation to reduce costs by up to 54% against other comparable protocols.
Type:
CORE
Motivation
Similar to previous versions of 0x protocol we want to support a thriving NFT ecosystem and offer traders the best experience.
Specification
Basics
Users can sign an off-chain order to indicate that they are interested in:
There are two Solidity order structs:
ERC1155Order has one additional field compared to ERC721Order, used to specify the amount of the ERC1155 being bought or sold. This would be used for fungible ERC1155 assets.
The
TradeDirection
enum is used to indicate whether an order is a bid or an ask:enum TradeDirection { SELL_NFT, BUY_NFT }
Order structs look like the following:
Upon discovering a listing, a trader, with the help of a dApp, will fill the ERC721 Order on-chain.
Collection/floor/property-based orders
In lieu of specifying a particular token ID, buy orders can specify a list of properties that an NFT asset must satisfy to be used to fill the order.
These properties are encoded using the following struct:
where propertyValidator implements the following function:
Fees
An order can specify fees to be paid out during settlement, denominated in the ERC20 token of the order. Both ERC721Order and ERC1155Order have a
Fee[]
fees field, where Fee is the following struct:If the
feeData
length is greater than0
then a fee callback will be called. The receiver must implement theIFeeRecipient
interface.ETH/WETH handling
A sell order must use WETH instead of ETH, since we require the ERC20 transferFrom functionality to transfer WETH from the maker to the taker. Even so, the taker can choose to receive ETH when filling a WETH sell order by setting the
unwrapNativeToken
parameter to true insellERC721
orsellERC1155
.A buy order can specify either ETH or WETH, i.e. the buyer can indicate whether they would like to receive ETH or WETH. A WETH sell order can be filled by a taker using ETH: the
buyERC721
andbuyERC1155
functions are payable and themsg.value
can be used to fill a WETH sell order.Pre-signing orders
Since smart contracts cannot sign orders in the traditional sense, they can instead “sign” orders by calling the
preSignERC721Order
orpreSignERC1155Order
functions.If an order has been pre-signed, it can by providing a “null” signature with the PRESIGNED signature type (see LibSignature.sol (https://github.com/0xProject/protocol/blob/refactor/nft-orders/contracts/zero-ex/contracts/src/features/libs/LibSignature.sol#L42-L61)):
Implementation
https://github.com/0xProject/protocol/compare/audit/nft-orders
Designated team
0x Labs
Audits
This change was audited by ABDK. Final report to be published here.
Bug Bounty
0x has an outstanding bug bounty for our contracts. For more information see the Bug Bounty page.
The text was updated successfully, but these errors were encountered: