Doc update (#675)

* Update existing protocol docs to point to protocol-specific resources

Remove documentation of outdated/irrelevant portions of the protocol

* pin jinja version to try to fixbuild failure. (#711)

---------

Co-authored-by: Eric Wong <ewong@Erics-MBP.fios-router.home>
This commit is contained in:
wonge97 2023-04-19 12:22:58 -05:00 committed by GitHub
parent ad2d41fd90
commit d7bc0b79df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 619 additions and 1591 deletions

BIN
docs/_static/img/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

15
docs/_static/img/logo.svg generated vendored
View File

@ -1,15 +0,0 @@
<svg width="1028" height="500" viewBox="0 0 1028 500" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M656.054 246.637C656.054 163.677 690.359 122.422 743.722 122.422C796.861 122.422 831.839 164.35 831.839 246.637C831.839 328.924 796.861 370.628 743.722 370.628C690.583 370.628 656.054 328.924 656.054 246.637ZM743.498 149.327C704.933 149.327 685.874 185.426 685.874 246.861C685.874 275.785 690.135 298.206 698.206 314.574L773.991 159.641C765.247 152.691 755.157 149.327 743.498 149.327ZM713.677 334.305C722.197 340.807 732.063 344.171 743.722 344.171C782.287 344.171 801.794 307.848 801.794 246.861C801.794 218.61 797.758 196.413 789.462 179.597L713.677 334.305Z" fill="black"/>
<path d="M1022.87 194.17L973.991 277.13L1027.35 366.368H994.619L951.794 294.17H939.686L895.964 366.368H864.126L917.713 278.251L869.507 194.17H900.449L939.91 262.556H952.242L992.601 194.17H1022.87Z" fill="black"/>
<path d="M105.022 316.009L143.834 275.852L95.583 210.74L34.148 123.812C12.4439 160.852 0 203.969 0 250C0 326.256 34.148 394.529 88.0045 440.381L165.987 385.269C139.462 368.744 118.094 344.686 105.022 316.009Z" fill="black"/>
<path d="M183.991 105.022L224.148 143.834L289.26 95.583L376.188 34.148C339.148 12.4439 296.031 0 250 0C173.744 0 105.471 34.148 59.6188 88.0045L114.731 165.987C131.256 139.462 155.314 118.094 183.991 105.022Z" fill="black"/>
<path d="M356.166 224.148L404.417 289.26L465.852 376.188C487.556 339.148 500 296.031 500 250C500 173.744 465.852 105.471 411.996 59.6188L334.013 114.731C360.538 131.256 381.906 155.314 394.978 183.991L356.166 224.148Z" fill="black"/>
<path d="M440.381 411.996L385.269 334.014C368.744 360.538 344.686 381.906 316.009 394.978L275.852 356.166L210.74 404.417L123.812 465.852C160.852 487.556 203.969 500 250 500C326.256 500 394.529 465.852 440.381 411.996Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="1027.35" height="500" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -62,16 +62,16 @@ Function timelocks are represented in days, where one day is equivalent to 86,40
.. csv-table::
:header: "Contract", "Function", "Selector", "Timelock"
AllowanceTarget, ``addAuthorizedAddress``, ``42f1181e``, 2 days
AllowanceTarget, ``addAuthorizedAddress``, ``42f1181e``, 2 day
AllowanceTarget, ``removeAuthorizedAddress``, ``70712939``, 0 days
AllowanceTarget, ``removeAuthorizedAddressAtIndex``, ``9ad26744``, 0 days
Governor, ``registerFunctionCall``, ``751ad560``, 2 days
ExchangeProxy, ``extend``, ``6eb224cb``, 2 days
ExchangeProxy, ``migrate``, ``261fe679``, 2 days
Governor, ``registerFunctionCall``, ``751ad560``, 2 day
ExchangeProxy, ``extend``, ``6eb224cb``, 2 day
ExchangeProxy, ``migrate``, ``261fe679``, 2 day
ExchangeProxy, ``rollback``, ``9db64a40``, 0 days
ExchangeProxy, ``setQuoteSigner``, ``<deprecation in progress>``, 2 days
ExchangeProxy, ``setTransformerDeployer``, ``87c96419``, 2 days
ExchangeProxy, ``transferOwnership``, ``f2fde38b``, 2 days
ExchangeProxy, ``setQuoteSigner``, ``<deprecation in progress>``, 2 day
ExchangeProxy, ``setTransformerDeployer``, ``87c96419``, 2 day
ExchangeProxy, ``transferOwnership``, ``f2fde38b``, 2 day
StakingProxy, ``addExchangeAddress``, ``8a2e271a``, 14 days
StakingProxy, ``removeExchangeAddress``, ``01e28d84``, 14 days
StakingProxy, ``attachStakingContract``, ``66615d56``, 14 days

View File

@ -2,7 +2,7 @@
Overview
###############################
The 0x Exchange implements a delegate-call proxy pattern to create a system of composable smart contracts. This architecture enables 0x to innovate with minimal friction alongside the growing DeFi ecosystem.
The `ZeroEx` (Exchange Proxy) contract implements a delegate-call proxy pattern to create a system of composable smart contracts. This architecture enables 0x Protocol to innovate with minimal friction alongside the growing DeFi ecosystem.
The diagram below illustrates our system (click to enlarge).
@ -24,13 +24,7 @@ The table below defines our smart contract nomenclature.
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Flash Wallet <./flash_wallet.html>`_ | The Flash Wallet is a sandboxed escrow contract that holds funds for Transformers to operate on. For example, the ``WETHtransformer`` wraps any Ether in the Flash Wallet. |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Allowance Target <../basics/allowances.html>`_ | Users set their allowances on this contract. It is scheduled to be deprecated after the official V4 release in January, 2021. After which point allowances will be set directly on the Proxy. |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Governor <./governor.html>`_ | A MultiSig that governs trusted contracts in the system: Proxy, Features, Flash Wallet. |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Transformer Deployer <./transformer_deployer.html>`_ | Deploys Transformers. A transformer is authenticated using a nonce of the Transformer Deployer. |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `Fee Collectors <./fee_collectors.html>`_ | `Protocol fees <../basics/protocol_fees.html>`_ are paid into these contracts at time-of-fill. |
| `Governor <./governor.html>`_ | A smart contract that governs trusted contracts in the system: Proxy, Features, Flash Wallet. |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| `PLP Sandbox <./plp_sandbox.html>`_ | `PLP <../advanced/plp.html>`_ liquidity providers are called from this sandbox. |
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

View File

@ -2,37 +2,22 @@
Proxy
###############################
The `ZeroEx <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/ZeroEx.sol>`_ contract implements a per-function proxy pattern. Every function registered to the proxy contract can have a distinct implementation contract. Implementation contracts are called “features” and can expose multiple, related functions. Since features can be upgraded independently, there will no longer be a collective “version” of the API, defaulting to a rolling release model. The ZeroEx contracts only responsibility is to route (delegate) calls to per-function implementation contracts through its fallback.
The `ZeroEx <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/ZeroEx.sol>`_ contract (also called Exchange Proxy or EP) is the main contract that manages the process and performs the exchange of assets. It implements a per-function proxy pattern where each function can have a distinct implementation contract, also known as "features". The `ZeroEx` contract's sole responsibility is to maintain a mapping of "features" to implementation contracts and route (delegate) calls to per-function implementation contracts through its fallback mechanism.
.. image:: ../_static/img/proxy.png
:align: center
:scale: 100%
View the code for the Proxy `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/ZeroEx.sol>`_. There is also a `gas-optimized implementation <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/ZeroExOptimized.sol>`_ that may be put into production in the future (there is a lot of overhead for our integrators when redeploying this contract).
View the code for the Proxy `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/ZeroEx.sol>`_. The deployed contract address for each network can be found in `here <https://github.com/0xProject/protocol/blob/development/packages/contract-addresses/addresses.json>`_.
Bootstrapping
=============
The ZeroEx contract comes pre-loaded with only one Feature: `Bootstrap <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/BootstrapFeature.sol>`_. This exposes a ``bootstrap()`` function that can only be called by the deployer. This function does a few things:
1. De-register the bootstrap() function, which prevents it being called again.
2. Self-destruct.
3. Delegatecall the bootstrapper target contract and call data.
.. code-block:: solidity
// Execute a bootstrapper in the context of the proxy.
function bootstrap(address target, bytes callData) external
Below is the bootstrap workflow (click to enlarge).
.. image:: ../_static/img/bootstrap.png
:align: center
:scale: 70%
Deployment
==========
At deployment, the ``ZeroEx`` contract goes through an ``InitialMigration`` that bootstraps two core features to the proxy pattern: Function Registry and Ownership.
Function Registry
=================
One of the initial features InitialMigration bootstraps into the ZeroEx contract is the function registry feature, SimpleFunctionRegistry. This feature exposes the following function registry management features: ``extend()`` and ``rollback()``.
``SimpleFunctionRegistry`` is one of the initial and core features of the `ZeroEx` contract boostrapped in during the ``InitialMigration``. This feature exposes the following function registry management features: ``extend()`` and ``rollback()``.
Call ``extend()`` to register a new function (selector) and implementation (address). This also maintains a history of past implementations so we can roll back to one, if needed.
@ -54,7 +39,7 @@ Call ``rollback()`` to revert a function implementation to a prior version in it
Ownership
=========
Another Feature, ``InitialMigration``, bootstraps into the proxy is the Ownable feature. This exposes ownership management functions: ``transferOwnership()`` and ``owner()``. This feature also enables ubiquitous modifiers such as onlyOwner, so it is an implicit dependency of nearly every other feature.
``Ownable`` is another initial and core feature of the `ZeroEx` contract that is bootstrapped into the proxy during the ``InitialMigration``. This exposes ownership management functions: ``transferOwnership()`` and ``getOwner()``. This feature also enables ubiquitous modifiers such as onlyOwner, so it is an implicit dependency of nearly every other feature.
.. code-block:: solidity
@ -256,3 +241,24 @@ Functions can be re-entered by default; those secured by the ``nonReentrant`` mo
**Colliding Function Selectors**
We manually ensure that function selectors do not collide during PR's. See the `Feature Checklist <./features.html#best-practices>`_ for a complete list of our best practices on Feature Development.
Initial Bootstrapping
=====================
The way that the initial bootstrapping is accomplished is through the ``bootstrap()`` function that can only be called by the deployer. Check `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/BootstrapFeature.sol>`_ to see the full boostrapping feature.
This function does a few things:
1. De-register the bootstrap() function, which prevents it being called again.
2. Self-destruct.
3. Delegatecall the bootstrapper target contract and call data.
.. code-block:: solidity
// Execute a bootstrapper in the context of the proxy.
function bootstrap(address target, bytes callData) external
Below is the bootstrap workflow (click to enlarge).
.. image:: ../_static/img/bootstrap.png
:align: center
:scale: 70%

View File

@ -295,9 +295,9 @@ In both cases, the ``@0x/protocol-utils`` package simplifies generating these si
The Orderbook
=======================
Orders are shared through a decentralized and permissionless network, called `0x Mesh <https://0x.org/mesh>`_. The simplest way to post and discover orders is through `0x API <https://0x.org/api>`_. See `this guide <https://0x.org/docs/guides/market-making-on-0x>`_ tailored for Market Makers.
Orders can be hosted by any server and are usually represented as a JSON object off-chain. For example, one off-chain way to post and discover orders is through `0x API <https://0x.org/api>`_.
Orders are usually represented as a JSON object off-chain. Below is a table represention and example of how orders should be formatted off-chain.
Below is a table represention and example of how orders should be formatted off-chain.
JSON representation of RFQ Orders
*********************************

View File

@ -0,0 +1,75 @@
Signatures
==========
Signatures are used in several places in 0x Protocol to prove an actor
has agreed to the behavior in some off-chain message.
Signatures are represented by the following struct:
.. code:: solidity
struct Signature {
// How to validate the signature.
SignatureType signatureType;
// EC Signature data.
uint8 v;
// EC Signature data.
bytes32 r;
// EC Signature data.
bytes32 s;
}
Where ``SignatureType`` is:
.. code:: solidity
enum SignatureType {
ILLEGAL,
INVALID,
EIP712,
ETHSIGN,
PRESIGNED
}
Descriptions of the valid signature types follow.
**EIP712 (``2``)**
This is the signature type typically used when an order is signed
through a UI, such as Metamask. This is commonly achieved by calling
some variant of the ``eth_signTypedData`` (which fully utilizes EIP712)
JSONRPC command on the Ethereum provider.
It can also be generated in a headless manner using a standard
``ecsign()`` implementation
(`example <https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_signature_.md#const-ecsign>`__)
by re-hashing the `canonical order
hash <signatures.md#limit-order-hashes>`__ with a prefix as follows and
signing the result:
.. code:: solidity
eip712HashToSign = keccak256(abi.encodePacked(
"\x19Ethereum Signed Message:\n32",
orderHash
));
ETHSIGN (``3``)
^^^^^^^^^^^^^^^
This is the signature type typically used when an order is signed in a
headless environment (e.g., script or backend). This commonly achieved
by calling the ``eth_sign`` JSONRPC command on the Ethereum provider or,
perhaps more straight-forwardly, using a standard ``ecsign()``
implementation
(`example <https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/modules/_signature_.md#const-ecsign>`__).
Unlike the ``EIP712`` signature type, the hash to sign is simply the
`canonical order hash <signatures.md#limit-order-hashes>`__ (no prefix).
PRESIGNED (``4``)
^^^^^^^^^^^^^^^^^
This signature type is used exclusively with NFT orders (721 and 1155)
for now. This value indicates that the order maker has previously marked
the order as fillable on-chain. The remaining fields in the
``Signature`` struct will be ignored.

454
docs/guides/nft_guide.rst Normal file
View File

@ -0,0 +1,454 @@
###############################
NFT Guides - Creating Orders
###############################
The easiest way of creating a 0x NFT order is to use the npm packages `@0x/protocol-utils` and `@0x/utils`
>>> yarn add @0x/protocol-utils @0x/utils
or
npm install @0x/protocol-utils @0x/utils
Create an ERC721Order
=====================
The following code snippet shows how to construct a basic ERC721 sell order in JavaScript. In the following example, the seller indicates that they would like to receive ether by providing the sentinel value `0xeee...`` as the `erc20Token`.
.. code-block:: javascript
const { ERC721Order, NFTOrder } = require("@0x/protocol-utils");
const utils = require("@0x/utils");
// Construct sell order
const sellOrder = new ERC721Order({
// The EVM blockchain that this order is for, in this case Ethereum mainnet.
chainId: 1,
// The address of the 0x v4 ExchangeProxy contract on Ethereum.
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
// Whether to sell or buy the given NFT
direction: NFTOrder.TradeDirection.SellNFT,
// This indicates that the seller would like to receive ETH.
erc20Token: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// The price, in this case 1 ETH.
erc20TokenAmount: utils.BigNumber('1e18'),
// Address of the ERC721 contract.
erc721Token: '0x5180db8f5c931aae63c74266b211f580155ecac8',
// Token ID of the NFT to sell.
erc721TokenId: 123,
// Address of the seller. This is also the address that will be
// signing this order.
maker: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
// A null taker address allows anyone to fill this order
taker: '0x0000000000000000000000000000000000000000',
// A unique order nonce
nonce: 420,
// Order expires in one hour
expiry: new utils.BigNumber(Math.floor(Date.now() / 1000 + 3600)),
});
An ERC721 sell order can be created similarly. Note that buy orders must use WETH instead of ether, because the ERC20 `transferFrom` functionality is needed to execute a buy order.
.. code-block:: javascript
const { ERC721Order, NFTOrder } = require("@0x/protocol-utils");
const utils = require("@0x/utils");
// Construct buy order
const buyOrder = new ERC721Order({
// The EVM blockchain that this order is for, in this case Ethereum mainnet.
chainId: 1,
// The address of the 0x v4 ExchangeProxy contract on Ethereum.
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
// Whether to sell or buy the given NFT
direction: NFTOrder.TradeDirection.BuyNFT,
// Address of the ERC20 token to buy with, in this case WETH.
erc20Token: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
// The price, in this case 1 WETH.
erc20TokenAmount: utils.BigNumber('1e18'),
// Address of the ERC721 contract.
erc721Token: '0x5180db8f5c931aae63c74266b211f580155ecac8',
// Token ID of the NFT to buy.
erc721TokenId: 234,
// Address of the buyer. This is also the address that will be
// signing this order.
maker: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
// A null taker address allows anyone to fill this order
taker: '0x0000000000000000000000000000000000000000',
// A unique order nonce
nonce: 421,
// Order expires in one hour
expiry: new utils.BigNumber(Math.floor(Date.now() / 1000 + 3600)),
});
**Choosing a nonce**
If two orders signed by the same maker have the same nonce, filling or cancelling one can result in the other becoming unfillable.
::
Two ERC721 orders with the same nonce cannot both be filled, but two ERC1155 orders with the same nonce can both be filled (as long as the orders are not identical).
You can use a pseudorandom value or the current timestamp as the order nonce, but nonces can be chosen in a specific way to enable more gas-efficient fills and cancellations. See `Smart Nonces <./smart_nonce.rst>`_ for explanation.
We recommend using the most significant 128 bits of the nonce as an application/marketplace identifier. The least significant 128 bits of the nonce can be incremented from 0 for each order created by a particular maker.
**Royalties and Fees**
0x V4 has flexible support for creator royalties and platform fees. Marketplaces can pay out royalties to creators in real-time, and even have the option to send fees to their own custom fee disbursement contract.
Fees are paid by the **buyer**, denominated in the asset paid by the buyer, and are paid **in addition** to the `erc20TokenAmount` specified in the order.
The following code snippet shows how to create an ERC721 order with a single fee. Multiple fees can be specified by providing multiple fee objects in the order fees field.
.. code-block:: javascript
const { ERC721Order, NFTOrder } = require("@0x/protocol-utils");
const utils = require("@0x/utils");
const fee = {
// Address to receive the fee. Can be a smart contract.
recipient: '0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c',
amount: utils.BigNumber('1e17'), // 0.1 ETH
// If the fee recipient is a contract, this field can be used
// to invoke a callback. In this case, there is no callback.
feeData: '0x',
};
// Construct sell order
const order = new ERC721Order({
chainId: 1,
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
direction: NFTOrder.TradeDirection.SellNFT,
erc20Token: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
erc20TokenAmount: utils.BigNumber('1e18'),
erc721Token: '0x5180db8f5c931aae63c74266b211f580155ecac8',
erc721TokenId: 123,
maker: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
taker: '0x0000000000000000000000000000000000000000',
fees: [fee],
nonce: 420,
expiry: new utils.BigNumber(Math.floor(Date.now() / 1000 + 3600)),
});
**Collection Offers**
In 0x V4, it is possible to create a bid for any NFT in a particular collection. The following code snippet shows how to create an order to buy any CryptoCoven $WITCH.
.. code-block:: javascript
const { ERC721Order, NFTOrder } = require("@0x/protocol-utils");
const utils = require("@0x/utils");
const property = {
// Providing `address(0)` and `0x` serves as the sentinel
// values for a "null property", i.e. any token ID from the
// given collection can be used to fill the order.
propertyValidator: '0x0000000000000000000000000000000000000000',
propertyData: '0x',
};
// Construct sell order
const order = new ERC721Order({
chainId: 1,
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
direction: NFTOrder.TradeDirection.SellNFT,
erc20Token: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
erc20TokenAmount: utils.BigNumber('1e18'),
erc721Token: '0x5180db8f5c931aae63c74266b211f580155ecac8',
// If one or more properties are specified in the order, the
// `erc721TokenId` must be 0.
erc721TokenId: 0,
maker: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
taker: '0x0000000000000000000000000000000000000000',
erc721TokenProperties: [property],
nonce: 420,
expiry: new utils.BigNumber(Math.floor(Date.now() / 1000 + 3600)),
}
Sign an ERC721 Order
====================
Off-chain orders must be signed by the order maker to be filled. For on-chain orders, refer to the next section.
**Signing with a private key**
Signing an order with a private key is easy: the `ERC721Order` and `ERC1155Order` classes from `@0x/protocol-utils` expose a `getSignatureWithKey` function that take a 0x-prefixed private key string.
.. code-block:: javascript
const { ERC721Order, NFTOrder, SignatureType } = require("@0x/protocol-utils");
const utils = require("@0x/utils");
// Construct order
const order = new ERC721Order({
chainId: 1,
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
direction: NFTOrder.TradeDirection.SellNFT,
erc20Token: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
erc20TokenAmount: utils.BigNumber('1e18'),
erc721Token: '0x5180db8f5c931aae63c74266b211f580155ecac8',
erc721TokenId: 123,
maker: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
taker: '0x0000000000000000000000000000000000000000',
nonce: 420,
expiry: new utils.BigNumber(Math.floor(Date.now() / 1000 + 3600)),
});
// Sign order with private key
const signature = await order.getSignatureWithKey(
PRIVATE_KEY, // '0x123456789...'
SignatureType.EIP712
);
**Signing with ethers**
.. code-block:: javascript
const { ERC721Order, NFTOrder, SignatureType } = require("@0x/protocol-utils");
const utils = require("@0x/utils");
const { ethers } = require("ethers");
// Construct order
const order = new ERC721Order({
chainId: 1,
verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
direction: NFTOrder.TradeDirection.SellNFT,
erc20Token: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
erc20TokenAmount: utils.BigNumber('1e18'),
erc721Token: '0x5180db8f5c931aae63c74266b211f580155ecac8',
erc721TokenId: 123,
maker: '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
taker: '0x0000000000000000000000000000000000000000',
nonce: 420,
expiry: new utils.BigNumber(Math.floor(Date.now() / 1000 + 3600)),
});
// Get ethers Signer
const provider = new ethers.providers.JsonRpcProvider(/* constructor params */);
const signer = provider.getSigner(/* address */);
const { domain, message } = order.getEIP712TypedData();
const types = {
[ERC721Order.STRUCT_NAME]: ERC721Order.STRUCT_ABI,
['Fee']: NFTOrder.FEE_ABI,
['Property']: NFTOrder.PROPERTY_ABI,
};
const rawSignature = await signer._signTypedData(
domain,
types,
message
);
const { v, r, s } = ethers.utils.splitSignature(rawSignature);
const signature = {
v,
r,
s,
signatureType: 2
};
**On-chain Orders**
Orders can be simultaneously "signed" and listed on-chain using the `preSignERC721Order` or `preSignERC1155Order` functions. Orders can only be signed by the maker address specified in the order.
.. code-block:: solidity
/// @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(LibNFTOrder.ERC721Order calldata order)
external;
/// @dev Approves an ERC1155 order on-chain. After pre-signing
/// the order, the `PRESIGNED` signature type will become
/// valid for that order and signer.
/// @param order An ERC1155 order.
function preSignERC1155Order(LibNFTOrder.ERC1155Order calldata order)
external;
If an order has been pre-signed, it can be filled 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>`_):
.. code-block:: solidity
LibSignature.Signature({
signatureType: LibSignature.SignatureType.PRESIGNED,
v: uint8(0),
r: bytes32(0),
s: bytes32(0)
});
The pre-sign functions emit the entire order as an event, so that the order is easily indexable by subgraphs and thus easily indexable by subgraphs and thus easily discoverable without the need for an off-chain database.
.. code-block:: solidity
/// @dev Emitted when an `ERC721Order` is pre-signed.
/// Contains all the fields of the order.
event ERC721OrderPreSigned(
LibNFTOrder.TradeDirection direction,
address maker,
address taker,
uint256 expiry,
uint256 nonce,
IERC20TokenV06 erc20Token,
uint256 erc20TokenAmount,
LibNFTOrder.Fee[] fees,
IERC721Token erc721Token,
uint256 erc721TokenId,
LibNFTOrder.Property[] erc721TokenProperties
);
/// @dev Emitted when an `ERC1155Order` is pre-signed.
/// Contains all the fields of the order.
event ERC1155OrderPreSigned(
LibNFTOrder.TradeDirection direction,
address maker,
address taker,
uint256 expiry,
uint256 nonce,
IERC20TokenV06 erc20Token,
uint256 erc20TokenAmount,
LibNFTOrder.Fee[] fees,
IERC1155Token erc1155Token,
uint256 erc1155TokenId,
LibNFTOrder.Property[] erc1155TokenProperties,
uint128 erc1155TokenAmount
);
The pre-sign functions also enable smart contracts to create and "sign" NFT orders, opening the door for potential integrations with e.g. multisig wallets.
Filling an ERC721 Order
=======================
The basic functions used for filling NFT orders are the following:
.. code-block:: solidity
/// @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(
LibNFTOrder.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(
LibNFTOrder.ERC721Order calldata sellOrder,
LibSignature.Signature calldata signature,
bytes calldata callbackData
)
external
payable;
/// @dev Sells an ERC1155 asset to fill the given order.
/// @param buyOrder The ERC1155 buy order.
/// @param signature The order signature from the maker.
/// @param erc1155TokenId The ID of the ERC1155 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 erc1155SellAmount The amount of the ERC1155 asset
/// to sell.
/// @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
/// `zeroExERC1155OrderCallback` on `msg.sender` after
/// the ERC20 tokens have been transferred to `msg.sender`
/// but before transferring the ERC1155 asset to the buyer.
function sellERC1155(
LibNFTOrder.ERC1155Order calldata buyOrder,
LibSignature.Signature calldata signature,
uint256 erc1155TokenId,
uint128 erc1155SellAmount,
bool unwrapNativeToken,
bytes calldata callbackData
)
external;
/// @dev Buys an ERC1155 asset by filling the given order.
/// @param sellOrder The ERC1155 sell order.
/// @param signature The order signature.
/// @param erc1155BuyAmount The amount of the ERC1155 asset
/// to buy.
/// @param callbackData If this parameter is non-zero, invokes
/// `zeroExERC1155OrderCallback` on `msg.sender` after
/// the ERC1155 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 buyERC1155(
LibNFTOrder.ERC1155Order calldata sellOrder,
LibSignature.Signature calldata signature,
uint128 erc1155BuyAmount,
bytes calldata callbackData
)
external
payable;
`sellERC721` and `sellERC1155` are used when the caller is **selling** an NFT, so the order being filled is a **buy** order.
`buyERC721` and `buyERC1155` are used when the caller is **buying** an NFT, so the order being filled is a **sell** order.
Note that the only difference in parameters between the ERC721 and ERC1155 functions is `erc1155BuyAmount`. This value specifies the amount of the ERC1155 asset to sell/buy from the given order, which may be greater than one in the case of semi-fungible ERC1155 assets.
Cancelling an ERC721 Order
==========================
All orders, whether off-chain or on-chain, can only be cancelled on-chain. The following contract functions are used to cancel individual ERC721 and ERC1155 orders.
.. code-block:: solidity
/// @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 a single ERC1155 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 cancelERC1155Order(uint256 orderNonce)
external;
Note that if there are multiple outstanding orders with the same nonce, calling `cancelERC721Order` or `cancelERC1155Order` would cancel all those orders.
The following functions can be used to cancel multiple orders.
.. code-block:: solidity
/// @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 Cancel multiple ERC1155 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 batchCancelERC1155Orders(uint256[] calldata orderNonces)
external;
Fetching NFT Order Data
=======================
To fetch collection-level NFT stats from 0x orders (e.g. floor price, total volume), checkout the following tools:
- `https://module.readme.io/reference/retrieve-collection-floor <https://module.readme.io/reference/retrieve-collection-floor>`_
- `https://api.reservoir.tools/#/2.%20Aggregator/getEventsCollectionsFlooraskV1 <https://api.reservoir.tools/#/2.%20Aggregator/getEventsCollectionsFlooraskV1>`_
These tools are not 0x specific but NFT data is somewhat universal so these tools should do the trick.

View File

@ -0,0 +1,17 @@
############
Smart Nonces
############
The `nonce` field in the order is a number the maker chooses to ensure uniqueness of the order, but it also has some other functions:
- To identify the order (in addition to the caller/maker) in cancellation functions.
- To identify the order when checking/updating its filled state.
- To potentially reuse EVM storage slots that mark an order as filled, which can provide significant gas savings (~15k) when filling or cancelling the order.
**Gas Optimized Nonces**
The protocol marks ERC721 orders as filled when they either get cancelled or filled. Instead of always using a completely new storage slot for each order from a maker, the upper 248 bits of the nonce will identify the storage slot/bucket/status vector to be used and the lower 8 bits of the nonce will identify the bit offset in that slot (each slot is also 256 bits) which will be flipped from 0 to 1 when the order is cancelled or filled.
.. image:: ./_static/img/smart_nonce_diagram.webp
:width: 600
To take advantage of this gas optimization, makers should reuse the upper 248 bits of their nonce across up to 256 different orders, varying the value of the lower 8 bits between them.

View File

@ -1,17 +1,39 @@
0x Protocol
===========
0x is an open protocol that facilitates trustless, low friction exchange of Ethereum-based assets.
Learn more about 0x Labs at `0x.org <https://0x.org>`_. Check out our code on `GitHub <https://github.com/0xProject/protocol>`_.
Connect with the community on our `Forum <https://forum.0x.org/>`_ and `Reddit <https://www.reddit.com/r/0xProject/>`_.
Chat with our team privately on `Discord <https://discord.com/invite/d3FTX3M>`_ or publicly on `Twitter <https://twitter.com/0xproject>`_.
0x Protocol is the trusted open source settlement layer for the permissionless global exchange of value.
This documentation is aimed to serve as the canonical technical documentation for 0x Protocol and the system of smart contracts that make up its full functionality. The structure of this documentation is as follows:
- Architectural Overview of the whole system of smart contracts that 0x Protocol is comprised of.
- Subsections will provide a deep dive into each contracts
- Tutorial and tools to get started building with/on top of 0x Protocol
To learn more about why 0x Protocol was created, read the whitepaper `here <https://github.com/0xProject/whitepaper/blob/master/0x_white_paper.pdf>`_ and at `0xProtocol.org <httpsL//0xProtocol.org>`_.
All code is open sourced on `GitHub <https://github.com/0xProject/protocol>`_.
Connect with the community on our `Forum <https://forum.0xProtocol.org/>`_, `Discord <https://discord.com/invite/official0x>`_, `Reddit <https://www.reddit.com/r/0xProject/>`_, and `Twitter <https://twitter.com/zeroexprotocol>`_.
.. image:: ./_static/img/logo.svg
.. image:: ./_static/img/logo.png
:width: 20%
:alt: 0x Protocol logo
:align: center
.. toctree::
:maxdepth: 2
:caption: Architecture
architecture/overview.rst
architecture/proxy.rst
architecture/features.rst
architecture/transformers.rst
architecture/flash_wallet.rst
architecture/governor.rst
architecture/transformer_deployer.rst
architecture/fee_collectors.rst
architecture/plp_sandbox.rst
.. toctree::
:maxdepth: 2
:caption: Basics
@ -34,27 +56,10 @@ Chat with our team privately on `Discord <https://discord.com/invite/d3FTX3M>`_
.. toctree::
:maxdepth: 2
:caption: Architecture
:caption: Guide
architecture/overview.rst
architecture/proxy.rst
architecture/features.rst
architecture/transformers.rst
architecture/flash_wallet.rst
architecture/governor.rst
architecture/transformer_deployer.rst
architecture/fee_collectors.rst
architecture/plp_sandbox.rst
.. toctree::
:maxdepth: 2
:caption: ZRX Tokenomics
tokenomics/research.rst
tokenomics/staking.md
tokenomics/staking_reward_formula.rst
tokenomics/governance.rst
guides/nft_guide.rst
guides/smart_nonce.rst
.. toctree::
:maxdepth: 2
@ -71,9 +76,9 @@ Chat with our team privately on `Discord <https://discord.com/invite/d3FTX3M>`_
:maxdepth: 1
:caption: Connect
0x Labs <https://0x.org>
0x Protocol <https://0xProtocol.org>
GitHub <https://github.com/0xProject/protocol>
Forum <https://forum.0x.org/>
Forum <https://forum.0xProtocol.org/>
Reddit <https://www.reddit.com/r/0xProject/>
Discord <https://discord.com/invite/d3FTX3M>
Discord <https://discord.com/invite/official0x>
Twitter <https://twitter.com/0xproject>

View File

@ -1,3 +1,4 @@
six
sphinx==3.5.4
sphinx-markdown-tables
jinja2<3.1

View File

@ -1,5 +0,0 @@
###############################
Governance
###############################
The 0x Community uses their ZRX (and staked ZRX) tokens to govern the protocol, by voting on proposals called `ZEIPs <https://github.com/0xProject/ZEIPs>`_. Anyone can propose a change to the system by creating a ZEIP. Visit `https://0x.org/zrx/vote <https://0x.org/zrx/vote>`_ to participate!

View File

@ -1,9 +0,0 @@
###############################
Research
###############################
.. raw:: html
<embed>
<iframe class="researchPdf" src="../_static/protocol-fees.pdf" width="100%" />
</embed>

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
###############################
Staking Reward Formula
###############################
.. raw:: html
<embed>
<iframe class="researchPdf" src="../_static/adjusted-staking-percentage-formula.pdf" width="100%" />
</embed>