V4 Docs. See live on https://0xprotocol.readthedocs.io. (#56)
23
.readthedocs.yaml
Normal file
@ -0,0 +1,23 @@
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
# Build documentation with MkDocs
|
||||
#mkdocs:
|
||||
# configuration: mkdocs.yml
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF
|
||||
#formats:
|
||||
# - pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
3
docs/.gitignore
vendored
@ -1 +1,2 @@
|
||||
_build*
|
||||
_build*
|
||||
basics/addresses.rst
|
||||
|
@ -49,38 +49,48 @@ help:
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
addresses:
|
||||
@python scripts/generate_addresses.py > basics/addresses.rst
|
||||
|
||||
html:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
@ -90,6 +100,7 @@ qthelp:
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc"
|
||||
|
||||
devhelp:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@ -99,11 +110,13 @@ devhelp:
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@ -111,6 +124,7 @@ latex:
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@ -123,16 +137,19 @@ latexpdfja:
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@ -140,38 +157,45 @@ texinfo:
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
xml:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml:
|
||||
@make addresses
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
||||
|
@ -1,6 +1,6 @@
|
||||
### Dependencies
|
||||
```bash
|
||||
pip3 install sphinx recommonmark
|
||||
pip3 install sphinx recommonmark sphinx-rtd-theme
|
||||
```
|
||||
|
||||
### Syntax
|
||||
@ -15,4 +15,4 @@ open _build/html/index.html
|
||||
|
||||
### Tips
|
||||
* Generate RST tables [here](https://www.tablesgenerator.com/text_tables#).
|
||||
* Set your editor's ruler to `100` characters.
|
||||
* Set your editor's wordwrap to `98` characters.
|
||||
|
1
docs/_drawio/RFQm.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2020-11-26T19:08:04.215Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" etag="CmJIcjcWDvJrr_8s4-lH" version="13.10.4" type="device"><diagram id="tQ2ikExJWypodGvSq9TR" name="Page-1">7VjRbtowFP0aHls5CUnhsUC7PawaE+22VxObxJoTR45ToF8/m9hJjEM7VFBVNB5QfGzfxOecey9kEEyzzRcOi/SBIUwHPkCbQTAb+H4UBvJbAVsN+OMaSDhBNQRaYEFecA16Bq0IwqXGakgwRgUpbDBmeY5jYWGQc7a2l60YRRZQwAQ7wCKG1EV/ESTSGh2FoMW/YpKk5s4e0DMZNIs1UKYQsXUHCu4GwZQzJuqrbDPFVHFn83J/YLZ5MI5z8S8bnuaJSGPw9HP19GM2nIPYf1xeRXWUZ0grfWD9sGJrGMA5ulVEylHOcglOUpFROfLkpZy8J1SNgByVAnJhFscUliWJDayXqU31LTBymG+P4jUESWNhlmHBt3LJupXAKJB22DcYxxQK8myHh9oJSROuucOcEXljH2jT+iMdR3t2aCQ0IUpW8RjrXV3K9wINwRuBJDEJFk4gedE5dgvtFD1C3RtH3QVJcowkJh/RB985wtwVXArzDS5lHltSQyr3Kl2lSHJXMHnGXBCZKbd6IiMIqRgTjkvyApe7eMoWhTrf7sThZBDOGgeoAHjTl8Z6c5s8XW8cNrJrGB39ClyDKLqxxLjy32cWE8bz7S1stSrxWeT0hm9na8JZVbyL3gOpZ3IjsC0djPW4k5rB6DqIQPsxz91N1TE4TLTF29EkORw9wj89LpfluFCXVUZvY8G6ht6Zf85KIghTxl4yIVjW43jBCjtHWCUoyfG0aUbgNbO/aeqaOFeLrd0ju9RHknqX7dHZ2B4f1UDantDbQ7z9HqIbTreBgM/YQMJTNZD9QGduIKY+9HWQh8ffl9E6ag9feO/w3d7x8Bnq4uvdaAhsXZp8+cCS6If/S2JPJQtPVBLDmw8uie5fpjuRYo6rTKKXUhNrE196TRy9IuWeivJndY4w0hKsUyLwooCxml1zuFfuTlDZHJv7bmWLetI1Or6syWH7FqLmtn2VE9z9BQ==</diagram></mxfile>
|
1
docs/_drawio/architecture.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2020-11-28T03:29:20.728Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" etag="nBDmVWjuDTcDQe5h0YVb" version="13.10.4" type="device"><diagram id="rftwT3FDcWazuVvmtWtw" name="Page-1">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</diagram></mxfile>
|
1
docs/_drawio/plp_sandbox.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2020-11-28T08:11:27.535Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" etag="lwVgew-5cziUpBAa_zXj" version="13.10.4" type="device"><diagram id="3GC5muPaEtQo6cA30gfC" name="Page-1">3Vhbc6IwFP41PLYDhCh9rJfuPtgZZ+1028cIATIicUOs2F+/CYS7KO1qL6sP5nxJDsm5fOeIBsbr5AdDm+CeujjUTN1NNDDRTNMwLCB+JLLPEd3IEJ8RN8P0EliQV6wW5uiWuDhWWAZxSkNONnXQoVGEHV7DEGN0V1/m0dCtARvk4xawcFDYRn8TlwcZakO9xH9i4ge8uJ+aWSJn5TO6jdTzNBN4jvxm02uU61Lr4wC5dFeBwFQDY0Ypz0brZIxDady62e46ZotzMxzxPhvch8enRyMk+iy5u4X+L/95NbxSWl5QuFX2mJE/wiOE7+eMvgjXsDuM+JZhdQm+zw2XXh1L5boGRruAcLzYIEfO7kSsCCzg61BIhhh6JAzHNKQs3QtchG1hKDCKOaMrXJkZODZeemJGHQwzjpPOGxuFHUWAYrrGnO3FknzDQJlexSbIXbErHV2sCSpOvlEYUrHlF6pL+4qBMvEbzG22zN0yK47cWxnWQnJCFMfEqVtS3J3tn5TVU+FZCtcmzOVJUp2d7JXkojhI3WUoYY44xyxKEVM3Cptjt5UxDYuLFEXMx/zITcFhz1QsDw8YPscYDhEnL/VjHPKGesKcEnHAwvGFo3PHWw2HxnTLHKx2VXOmoWigNxWBuqLMDi1FaXAU135/vFiteDGuhfzAUBR7mMkhWmW/Io2iuB1NwpcztBSkXQsiFBJfOt4RfhXbwUjmGRGkeKsm1sR1pY4RwzF5RctUn4yijbxqenk40uDkWKIqxlabSyKshlN3lnRm9ZV+behDs+YX4yxhY8Ca0qubugLqeTG+iJtBy83z2VwABReLcU7HZ+VhD8rvQR5OP3IHjXgFzz7n4eeB9U5+ti/Fz/B/LodWg8wK+dPMPThDOUwIf6qMs2I4hEosa6EU8lIoWXGhnkEZD6hPIxROS3RU92b/upgVltMN18n6CT+zfjYjBTYjoG/9tGBDEWgo6qifwuVoX1mmqk53wW92erZ99FzN9ZZV653FIDvBWVl++O/R3qOH6+oPh6f6w8OZ9GUTCfZMpE9tRL9dIsHjiXGyQX7remB/QOLZrcQzZRc9TbCz5Tjrp912Rf/qvfOJam83LD0c9I7evKtuxNjlGuCbD6bGa1glR+MUM55kuZw7S74s9HZy58WYEfRkxo74+RhmHJqHiePLMmPzwBAeZzrTOrr+MkyXZ2yT6iovDO6/9wuDt5EebEZVj78uQixfymaOKV99g+lf</diagram></mxfile>
|
BIN
docs/_static/adjusted-staking-percentage-formula.pdf
vendored
Normal file
BIN
docs/_static/img/architecture.png
vendored
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
docs/_static/img/bootstrap.png
vendored
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
docs/_static/img/events.png
vendored
Normal file
After Width: | Height: | Size: 118 KiB |
BIN
docs/_static/img/fee_collectors.png
vendored
Normal file
After Width: | Height: | Size: 31 KiB |
0
docs/logo.svg → docs/_static/img/logo.svg
generated
vendored
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
docs/_static/img/plp_sandbox.png
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
docs/_static/img/proxy.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
docs/_static/img/rfqm.png
vendored
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
docs/_static/img/zero_ex_migrate.png
vendored
Normal file
After Width: | Height: | Size: 60 KiB |
10
docs/_static/js_overrides.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// Open external links in a new window.
|
||||
$(document).ready(function () {
|
||||
$('a[href^="http://"], a[href^="https://"]').not('a[class*=internal]').attr('target', '_blank');
|
||||
|
||||
$(".researchPdf").height($( document ).height() * 0.8);
|
||||
});
|
||||
|
||||
$( window ).resize(function() {
|
||||
$(".researchPdf").height($( document ).height() * 0.8);
|
||||
});
|
BIN
docs/_static/protocol-fees.pdf
vendored
Normal file
BIN
docs/_static/staking/Batch-Calls.png
vendored
Normal file
After Width: | Height: | Size: 46 KiB |
1
docs/_static/staking/Batch-Calls.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-10-24T17:44:23.702Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" etag="a1PqmrH1q441ueh3qvyw" version="12.1.4" type="device" pages="1"><diagram id="crgTK5YC3k6BpgnL1wcc" name="Page-1">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</diagram></mxfile>
|
BIN
docs/_static/staking/CobbDouglas.png
vendored
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
docs/_static/staking/Epochs.png
vendored
Normal file
After Width: | Height: | Size: 25 KiB |
1
docs/_static/staking/Epochs.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="www.draw.io" modified="2019-11-15T02:06:07.887Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36" etag="RBDA67A9Azio2FRpUQ5l" version="12.2.6" type="device" pages="1"><diagram id="RPvN8ENc-rlOBSpfUzvq" name="Page-1">5ZrbjtowEIafhsutkjgnLhf2pEpVV0Jqr914IFZDTB2zQJ++DnEgybDbbhXSqGYviH/b49jfeD1jMSHz9f5R0k36STDIJp7D9hNyN/E8141D/VUqh0qJIlIJK8lZJTlnYcF/gulZq1vOoDBaJSkhMsU3bTEReQ6JamlUSrFrN1uKjLWEDV0BEhYJzbD6lTOV1vNynHPFE/BVqro1a1q3NkKRUiZ2DYncT8hcCqGqp/V+Dlm5eu2FeXil9vRmEnL1Jx3UIn76cTN9nn6GL8HHeH/YLsmNX1l5odnWzNi8rDrUSwA5uy1XUpeSjBYFTyZklqp1pgVXPxaKSlW3ENpSrT3wrGzj6LK2YUplj6V+nItMyOMAhFGIl8mxlxTfoVETJjF8W+oaPFczfWAtfmbmjyDWoORBN9idqQUGRNrgVWsSMqr4S5s6Nc6zOpk7jfAsuH4Tz6kd3Td2jJt7sfMhaBspxFYmYPo1MXVMRfFvTenFXYFCpvRDY+pn6egH7/CJ4F0+kYtcizNGixSYAdzwjrGTO21Ps9zE+2tyXVNe7RQDcQtt4kac3rh1TQ3NLbKKW9wft+5/yoG5xTZx88PeuHVNDc1tahO3wO+NW9fU0NzqnMAOcGF/gUnX1ODgXJvARf1FJl1Tg4PzEDgXkVOwV92MsJnHGZzNpM9INOOrXBcTTRK0PnsBqbhOvm9NxZozVg4z26VcwWJDk3LMnaQbrUmxzdnRQcoMcyly1cgcnePnLW8px4L9m/7yWlw/PQFteFR8waM853XnabF6NxiCwOAt9d+DQYH7CMDgCxViIZhuZD4CMPhWw7cPDAq9RwAGX1sE9oFBsfUIwOB7idA+MCh2/vdg6qO+AeZ+I5L0CnBkNZ2RskG37hfZRIOywee/cwUuV9g00W3511PE3AUTXALjDwoGHzOuhWRIHQedyLiIy6Xc+Hpc8C2qjTuGTKMPIyND8HUbsZCMH42NCz7+fQu5BMH4dgw+/AMLyYRkbFxwJnNHD0WJhed6iTznEXIoeHEFVv1H0H2iQhH0BVQ9xc+6eP6tU3VBff7JGLn/BQ==</diagram></mxfile>
|
BIN
docs/_static/staking/ProtocolFee.png
vendored
Normal file
After Width: | Height: | Size: 75 KiB |
1
docs/_static/staking/ProtocolFee.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-10-23T18:15:35.959Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" etag="zDzUUwQKnwqpJevNYwl6" version="12.1.4" type="device" pages="1"><diagram id="crgTK5YC3k6BpgnL1wcc" name="Page-1">7Vpdd7I4EP41XtrDh1C9rB9tL953T9+257S+N3siRMiKxA2xfvz6TSBoSECpi63tbr0omYxjmOdhJjOkZQ/m6zsCFuFP7MOoZRn+umUPW5Zlml2X/eOSTSZxe1YmCAjyM5GxFzyhLRTfzKVL5MNEyDIRxTiiaFEUejiOoUcLMkAIXhXVpjjyC4IFCKAmePJApEtfkE/D/L4MYz9xD1EQUnVmDnJtIUhC4OOVJLJHLXtAMKbZ1Xw9gBH3XtExtxWzu5URGNM6X1gv6Lj7Or9dzTHdxn+/jZ1t3DYFPm8gWopbFqulm9wHMPZvuCvZyItAkiCvZfdDOo+YwGSXUxzTAY4wSdVtZ8A/TA595kphBhMa4gDHIBrtpX39FsRd8a9KAnFDdxDPISUbprDag+EI/4YSDLmMwAhQ9FYEEwhOBDtzu194wIitxDIEf7vCjCCv7RpFCwleEg+KL8muV+xYRtFQx1IMUUACSDVDzO1gI6ktuEJSvV6zYsFV61L1OyqFat6H0GcX2YrzkQTZXpTS8h0U/Z+hn8BQ27hMhubrOivjHI1xmPiQaLQjeBn7kFsyGFVWIaLwaQE8Prti6VDhIIoiiYNTh3+YPKEEz6A00x/yzwHWVnLyDRIK1wdZmc/ailvzgCSx1i5hbUdhhUxQCZP3u7zz/V1uKS63P87l15P7v9zteHRzszTe7pbjED3O2qbm8ka97QPYnXpl3na9LpxMm/FqR/VqCZG7JV7tnsurHevEdOWDJExdbRbdmrDIS3P1GMcwl90ivrIUGeY/snmVB2M+uHLy4XAtTw43u5EvrPBfgmtEX6VryQYb7U3wQW6hEsIs8RynX5ZXDjnUrplwBSPaxpVhOQVStM2uRooz5mQnX7L4eat3YlJ2DKtIbjUWVCTlvaFcEU+nCSzonJArD8LztcOI07m0MKInxCcKZigOmHDAshQBHgf4geD1RnM4u2uqRhHZeyKMyK4WIhChIOZxifmSpV+7z32IWD18IybmyPfTnXEZjEWgmwjvKi6OjkunBBe1vmoOF70aKcPlu+LhuBeGh3NqupWwODV7VvrzaE67rBrSbqqItM2iIbdmEdlULjJ1MozWXghi5maVFEeyEEgWWTtxitb8AapfS7jpn15LZH/NPIa2Wq1/YLpK7v4M6OvLj3D7+Hscvv7x+PDrV0kt8RPMSsq3JAQLfrmcRzcexXJA+wEmMHrACaII88A2wZTiOVOI+EQfeLMgDWcyCOlfSVCkWIETL2mEYgZT3iVuKj8pOHR0HMpqOvUBaw4HvXVxKBxipqd3ykQXnj1NVRXCvioYt6SioLRCyDNYBKf0CzTU3F6v/NF6bzBUDWmgNxcMy6mg71Ses2fSYJiAmAU+y2inE8YtZAM34vhMmIIb8KtD+03JRMvqS0aObnwITNAWTFIFTg/RMGTaTr/lDHXCVG54asQFlc06+Q4/RWoc2L1nEjfQkt/klMUH40opBRvhqHWl1rdFC41Ue6VtOr3Y+3ZtOvO0kH62zuj18Yj+3bKqpWHgahhYH4lBycYyjaXJfw6KjtH7ZChq7HC+Owi7ffyngVAjKJ36TrbSXxeyQTSvz/XK9XwbxHIQu+cD8fiL9U9oulgXxSO1dtTOhNTlUa9o57rm2ZLGaNR7F41EX7MOh3al50HcLxTO08PCsW7cmfHM6dM8njViwpdGXO12nhvx9569sdTMVTxLc1y/eFbnX5+9KX/B0sDWot4rc7mxdelcc9VjDqdGF1d9gfPR0UWvpF5Gz/dM8sxq/ViD+ku36TVnn69Nz4b7k8QZWPsD2fboHw==</diagram></mxfile>
|
BIN
docs/_static/staking/Read-Only Proxy.png
vendored
Normal file
After Width: | Height: | Size: 46 KiB |
1
docs/_static/staking/Read-Only Proxy.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-09-25T05:51:10.464Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" etag="Au58SNaQHwr2cnelpgaH" version="11.3.1" pages="1"><diagram id="crgTK5YC3k6BpgnL1wcc" name="Page-1">7VlLd+MmFP41OqddaI7edpa2k8ls2uZMFp2s5mAJyTSy8CCc2Pn1BYQQ6GE7fiSZabOJ+O4VhvvdF8jyZ8vNLQGrxR84gbnlOcnG8q8tz3PdccT+cWRbIaMrCWQEJVKpAe7RC5SgI9E1SmBpKFKMc4pWJhjjooAxNTBACH421VKcm7+6AhnsAPcxyLvo3yihi3pfjtMIvkCULWhbsgS1tgTKBUjwswb5N5Y/IxjT6mm5mcGcW682TPXe5wGpWhmBBT3kBRuPnNEmvX2Z/bjz/yxW38ehbV9VszyBfC13LBdLt7UJCF4XCeSTOJY/fV4gCu9XIObSZ0Y6wxZ0mbORyx5TlOcznGMi3vUTAMdpzPCSEvwINUkUj+E8ZRK5AEgo3AzuzFX2Yp4G8RJSsmUq8gW/NrF0sqjm4LmhbCyhhU5WJEEgvSRTUzd2ZA/SlP1mHc2//BO9PNxMJmvn6Xb9sEBfH233g5i1Y8MeSw+aVZnnw5g18Dp2ZQkHZoBCy4ty9vvTOWFPGX9iQZx30Q4PsEgmPFGwUZyDskTcrgkoF4Ib1+ShpIDQWr3ABayxz4jvRFDJDE623/TBAx988sJ6fL3RpddbNUrkNO4uAmFipKxB+mznk8N+U2fQdscdBsMeBmuMwBxQ9GTmwj5W5SLuMGKLVSvwgpYDBS3HKPGaxFC+paeu1kSdAG9PxCjIIN0xUa2I07SEho5wRGW9E3zT/xViPvx4MR907HpPwSMqMgbOMIsgEHOG7wjebDsWZ9um7RDWzSdjWLe1hECOsoInBWZMyPApNyJiSWUiBUuUJPxnenk0mT5HMh63iPG6xAQ9xHgX4yU6iJdflY+wzYf7znyE3dp4WK3TuBgqXfsql1EWMVtBqyzurGdV7t7fTO2te29T1Nq8j4+saa45z5VzWEk7olz1Nv5uX7mKwJIHSzEvV00DZWAHBDSBJXoBc6HAnWPFtyA2FU6t8PpVoZyDOcynIH7MRABrRS8Vf7vOD/JIKFdiqcjTXXBHJO3qq3yzrXLP4lhu0DfpWRuXXk+4bE8ts/dpDXWijzaIfqvzFXvWm2s2bDIUH6jWmuWOe7k+TOgCZ7gA+U2DTntzzGsOoe/fbgfOmdrtoJ3j2s3d27bbvV7b7QpP8MJ+nzrVpQzfbuptf2E8xvPeya2OrXjHuhUzIdhqarKgDC94oEQ3HljNeFZ/DDv++BWCxP6ryLc/xeHktAs4f38zHF2oGe5lo3s2OSU7XLB4vE0I+61T/ajdbB4cwvtywZlCuL3gNwnh0aucZv9l4SsrxMC5qe9W8D/gae2LqFE7V1zI00beG3ia2/d9oOqqyxUoDJ+Lfqz5F6Jpigtqp2CJWEHxJxZfpjyasdOQH3DXg/kT5FWgIxHas753AEEgH9YvQVHaJSQo5ZAQiHWU4kMdX4Wz2ijRXB3U7LiqV1yDZPPfWE1Wc3rBVfMcOr83W2zOE2H7k2LIrMtR8blMjWprh8LeDLnmz3zykFs0ZCzu03WVbh1ER03jNdNUpCpJipm/2wTyAivkzemKDaoDVf1qxbp6VfQHbFQlFQ67Yqh3CRwV9YsLmk7BgKtugUOyX+Cg2TFwoewZuFDrGrhE9A0crzsHDjoC0fZddRCHWFaJlFGbRBXy0FSagcaCs23wkY5Xqa2ZXZfJHNcQpclYjlB4pi2gzbkYKuJ10HRHqWf6bcrZqGKb5YoqvAeOzT/3XcpwTR3sG9mR2Y/Maw/7xMuUy5883e6FiRnj7euRJuBluP9PuxP5kUm79360WzKONfUmgv2bfwE=</diagram></mxfile>
|
BIN
docs/_static/staking/Rewards.png
vendored
Normal file
After Width: | Height: | Size: 102 KiB |
1
docs/_static/staking/Rewards.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="www.draw.io" modified="2019-09-25T03:03:09.000Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" etag="h5ObkhPmFjpkC9G2VWmF" version="11.3.1" type="device" pages="1"><diagram id="VLNjMBZskxfDaM01FNV8" name="Page-1">7Vltb6M4EP410X26E2AM6cc22+2dtF1V7Um3+9EFJ1gxmDXOJtlff2MwLwayTaOkqaJGquoZ48E8zzDPxJmgWbq5kyRP7kVM+cRz4s0EfZp4nutOA/inPdvKE/ph5VhIFlcup3U8sV/UrKy9KxbTwvgqlxKCK5bbzkhkGY2U5SNSirV92Vzw2HLkZEEHjqeI8KH3PxarpH4ux2kn/qZskaj+TErqq42jSEgs1h0Xup2gmRRCVaN0M6Nco2cD83nHbLMzSTO1zwL6FUVX+I7PHje/8uUc3f54/Pqnb/j5SfjKPLLZrdrWGEAYgBuMm3XCFH3KSaRn1sA4+BKVcrBcGJIirziYsw2Fu97MGeczwYUsA6EY02nsg79QUixpZ2bqPaMggBmzGyoV3ex8TrdBD/KOipQquYVLzAIcoGqJSTnfw5W9bgkMDSdJh7raR0zKLJrILagwMLi+AmOELw5jFDg2xnXWdzB2vRGQG+fxUXYuDuWpDXIDegdkzxkBuXEeHWR/D4yz+FoXXrAykWmsY1IkGsQS2Q7Ic5GpDnLVB/yAjtx+A6fz11Vtfi/NaW1+0gg5jbXtWg9UMnhaKmvnhqkqWjjFxq7COY3dxtPGtmP0o1XPS+OBbLxIaoc1PEJa7ZOUE8V+2uHHiDR3eBAMbtzkjIdCO2nC0A5RiJWMqFnVlYt+oN4rjvtvriJyQdUgEJBPtp3Lcn1BsXvDbi/L/cCSMRhUEdukbTA9PI/3Ub02jyNOioJFdvZaWb0rld99tvjj4L86WwaC0A+0I1uORejVgNB/hSJ62SNdExlDAjr/ZHo/8HcHgOnxbS6iZEA81GtlU20XeVPVuopgXISzRabzBcjVBeNGV38GzeS1mUhZHPNd8iPFKovLjHJOIh84HJEPd1Q+TqQerjdgqWKn7MylYeeeyCVV5WBJ5R+auRxa/svlCbnYJgqdnSj0Fjr/3oujH/ZqGjqwOA4CTU8jpb53Bil1X9cTXq6W+i9J4L7pgs+spe70g9Hx9+ngAtALhPbspY/G6LA9+lx+sdX7wI362sp7AsHldK7OLre+Z58PjX6tflO5rQO/QM9D2QU59zR9prI4AT3vpB/CdQGq+6Gxw6XgTQkanuCNvyJFQnI9XKX8OlKii+UX8kz5gyiYYkJj+iyUEilcwPXEDYmWixLJTqGcl58RPpTonVeJleIsA6rrU3DHIuZ3RXhA/jFeMcfuaJuC3GEQjRDYF7rjHQ6Gr5K0C21og76e+QfqWYB6gfpn50dqaPHVGRpa9NH+7EiXQxva8KVAJ25/8PDc4aNyj1fuAVVjZxEjKefjE1VuPGxdr1OAR6dXLkUupGalPOlToqQUhPlye6MA9yvv8MfNY/VGYLa/TlfvYvsjP7r9Hw==</diagram></mxfile>
|
BIN
docs/_static/staking/StakeManagementExample2.png
vendored
Normal file
After Width: | Height: | Size: 563 KiB |
1
docs/_static/staking/StakeManagementExample2.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-10-24T16:40:40.897Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" etag="VS_apb5ZDKD22CDafwDj" version="12.1.4" type="device" pages="1"><diagram id="TyhkYwz_4ZUKpUbEjiwx" name="Page-1">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</diagram></mxfile>
|
BIN
docs/_static/staking/Staking Architecture - Basic.png
vendored
Normal file
After Width: | Height: | Size: 111 KiB |
1
docs/_static/staking/Staking Architecture - Basic.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="www.draw.io" modified="2019-10-28T18:12:31.298Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" etag="8pos8loE_66jG-EgIaLq" version="12.1.8" type="device" pages="1"><diagram id="7wtnR19x4iwjK9TTFHl0" name="Page-1">7VrLcqM4FP0aL5PibXqZOK+qqVR1xT2T9OwUEI+KjFxCbsN8/UhGYJCwQzwYmKSdRdDVRUjnHF2JK2bmYpXdE7COHrEP0czQ/Gxm3swMQ9ddh/3jlrywzC29MIQk9oXT3rCM/4HCqAnrJvZh2nCkGCMar5tGDycJ9GjDBgjB26ZbgFHzqWsQQsWw9ABSrc+xT6NyXJq2r3iAcRhRuWYFSm9hSCPg423NZN7OzAXBmBZXq2wBEUevBKa47+5AbdUzAhPa5Ya3P/789vAUXmR3gbVB9yQPH4ML0covgDZixKKzNC8hIHiT+JA3os3M620UU7hcA4/XbhnpzBbRFWIlnV0GMUILjDDZ3Wv6ALqBx+wpJfgN1mocz4WvAatRh1H2CRIKs5pJDOse4hWkJGcuotZwBcRCZEbJwXZPWekS1ciyLGEEQiVh1fQeR3YhoPwArIYC623mRSBhYusT3sDmf63w7n78DpzQmr349QO7bpwGu3su1E0F9SUFb5CkM97Tu5nhINaF61fCrkJ+dQMRDAHFhz0exf2y/RPTaBoj02gpND4DhCDtQsM7wIN0XawSQZxxsqbNhO2MzIStMHGP2XASkDB8DW2ZpxSuvhor1aoxFiuOwopfxDGoUsF2MqgDQTDxr/huiZU8BNI05mu2D9JoF9H0Jl0pBYSW7glOYGm7i/lAdgGQwU3yl3rhJy9c2mXxJqtX3uRVyRet8CfBLKYvtetaG6y0b4IXyhYOMp7iDfHg+3shNpIQ0iN+88IP+o2t40H9XGiXmmE3JHShu4qE7BYJlTYCEaDxr+aetE1XohPfccwGX/XA0sxmhLclaRbQiLvqW0ipIdMxmlNBkxoqsDvSUOmIgyCFDZ/dVKjQO312zJXZ0etaPcyOtooxk9nRuq17qzgJmXHBgi8BHuf3O8FZrgDORk3lGFJHTwSROtTCBFAcJjwqMSwhs19zDGMW1a5ExSr2ff6YVhqbRPfAi6lJvJiGwovVwotxLlq+daLls9JhOROjo0xbHIs+rWttjYtTl86DeL67oOkdF7RhVitDin2WzFbX1UqfNxtynG6rVV8rkd4huVITg5hibUrQh1KC9VsJ9YYYNSCvua25Q9q9w47WSMmxi6LFfmWmJpumLjP7t8z6lJnlDiEzNbv2QZkN+jJnTEti8r5RVkZXib2r1TNJrCyfV2Jq5m/KEjMnLTFTzj9NXWKmM4TE1JSmIrGQvaesD8pCeTupDh/Ba9mCNmsVgrjL7nBuUoIxTEZRV1OKxyZe62tLt6xgPbunQnyUsrHnWZXzOm1aybNq4HcRNS3Wmr9hRtrvGeU4R8CjH53oasLs76cXZvgLbJCakvmPJyTDgGzL6ZaxD3x1Nf01StyaVgLFUfdul/ZpQcuRv6xQmzpz4CrXyvqnFE8LbpUPta7S3YnCgRT0//oIUqFh7IlnqKmtIrr9YOAknwt8V353Gx38jyV8vkjUm8uL0+lRT2F8+KinJlueb388fM4JJm8rRv8AyfhYHuKLTDD5tdU8NYel8N3buQwr7r+nLdz3nyWbt/8C</diagram></mxfile>
|
BIN
docs/_static/staking/Staking Architecture - Catastrophic Failure.png
vendored
Normal file
After Width: | Height: | Size: 142 KiB |
1
docs/_static/staking/Staking Architecture - Catastrophic Failure.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-10-28T18:21:37.591Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" etag="bH9ej-B20WLDISuJCRX8" version="12.1.8" type="device" pages="1"><diagram id="crgTK5YC3k6BpgnL1wcc" name="Page-1">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</diagram></mxfile>
|
BIN
docs/_static/staking/Staking Architecture - Read-Only.png
vendored
Normal file
After Width: | Height: | Size: 158 KiB |
1
docs/_static/staking/Staking Architecture - Read-Only.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-10-23T17:07:25.888Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36" etag="V3XMvYNff6c_R00PnPte" version="12.1.4" type="device" pages="1"><diagram id="crgTK5YC3k6BpgnL1wcc" name="Page-1">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</diagram></mxfile>
|
BIN
docs/_static/staking/Staking.png
vendored
Normal file
After Width: | Height: | Size: 63 KiB |
1
docs/_static/staking/Staking.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<mxfile modified="2019-10-04T17:48:48.214Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" etag="DYVuR7m3aPACEgmmvcHS" version="12.0.2" type="device" pages="1"><diagram id="crgTK5YC3k6BpgnL1wcc" name="Page-1">7Vpbc9o4FP41PML4gh3yCCRNH7qdlOy00JeOsGVbG2ExtgiQX1/JlkCW7OACSWhmyUwiHUnH8nfuh3Tc8WJzl4Fl8g8JIe44VrjpuDcdx7Ft32Z/OGVbUq76ghBnKBSb9oQH9AwF0RLUFQphXtlICcEULavEgKQpDGiFBrKMrKvbIoKrT12CGBqEhwBgk/oDhTQpqQPP2tM/QxQn8sm2JVYWQG4WhDwBIVkrJPe2444zQmg5WmzGEHPwJC7luU8Nq7uLZTClbQ5czT//5z/PbofDlfV0t5olaPLYFVyeAF6JFxaXpVuJQEZWaQg5E6vjjtYJovBhCQK+umYyZ7SELjCb2WwYIYzHBJOsOOuGAA6igNFzmpFHqKz4wQDOI7Zivoa8E8wo3Cgk8Vp3kCwgzbZsi1yVEAsd8+V8rUhMkBJFWJIGhI7EO857GNlAIPkHqPadw7DCNBxy/WSzAIM8RxymEORJAbVdhTWnIKNye0pSKGmfEL9ZIRmGX7adqpMZn/Q8Ob3ZqIs3290sFFz4k+AG0akyVniw2Z4Fn0gOjSLMySoL4GH1Y28SQ/oSoG65EYYVa23UiK7VsxyvohRde2AohVejFJKWQQwoeqq6gTpNEZe4J4i9/e4GjryyeLx3rSlbiY04pZqtzshyqsrd1xiV4L3ASG4kUZTDyp5CuXfonaDv7kdwI07/0txI34D1gYJHlMaMOCbMikHABXyfkc3WAJy9NdW9iIqecCMq1IIEMIpT7pcYlpDRRxxDxGLiUCwsUBjyx9SKsSroc7h3XS6eKZd+jVycV5OL30ouH1Uejn9h8vCODbeKLI6Nno14HoxpdsuQ9jbxaqDJ1D8yXNlVPtdWu2h1rkh01SKhjZlFLNvbwa62AHPJwaqXlDjltkhHXf9NA8nV6QbSLgVVU0kT4hdF9t6GsK16rj9VfC1ItczSzqX3ZgL2czJlhO9ghc1QdCD7AvmyLKUjtOGB433SMVcPM++djl1fhhFdiLlItdeTM5/HzOMsyIxBOqtXtiIZvBQR307GXO98zHO3ecZGMR8N86KUaki9T7SvyOM/tfZVfPgJlmUq9PJzHrszxPDedmeb6V3p3P5l4KQfC3zfujDw+/97vRpX5emx6XivZ0j8Nb1efvcrptMfX5Lnyc9ZMv06uf/2raYHzKtZVmjqcs4TsOTD1QIPA0rUSvQLmEN8T3JEEeEV6ZxQShZsA+YLIxA8xkUdqhpa8ampZinRTJasKEYpM0XZ4j9TIetqyLs1eXqNDuml0TG2Vi+IFsWLYmuE7dPaZswxia9QmNNsau3u27mzjtLNrW3tytYDhhE9qdPbtoH7RlmLZnTeseXuQUavbbtmbCyMl5GY7EAa8BGJ2C9p0+x+o2Kj9dVQLrNFlcEcPYvCl+vDkr9I8WreqOPdmBrS2Jpq4Qh09TW17WWzOblyt3rVpr1zFmVzKjy72vmzdOXrcfH+WndyIW7Cd6971W+RfL2J2TrMG6ze3FWYXWuRQDe6iu7OUej1T8PJStPhA3oaaVGX6ml6+neep/saNt3/j0K5ff+fHu7tbw==</diagram></mxfile>
|
BIN
docs/_static/staking/reward_tracking/Reward-Final.png
vendored
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/_static/staking/reward_tracking/RewardAfterManyEpochs-InPractice.png
vendored
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
docs/_static/staking/reward_tracking/RewardAfterManyEpochs.png
vendored
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
docs/_static/staking/reward_tracking/RewardFromWhatWeStore-Example.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
docs/_static/staking/reward_tracking/RewardFromWhatWeStore.png
vendored
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
docs/_static/staking/reward_tracking/RewardSingleEpoch.png
vendored
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
docs/_static/staking/reward_tracking/WhatWeStore.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
30
docs/_static/theme_overrides.css
vendored
@ -10,4 +10,32 @@
|
||||
.wy-table-responsive {
|
||||
overflow: visible !important;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
td ul p {
|
||||
font-size: 0.9rem !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
|
||||
.strike {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.document a:visited {
|
||||
color: #2980b9;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,27 @@
|
||||
###############################
|
||||
Audits
|
||||
###############################
|
||||
###############################
|
||||
|
||||
Below are links to our third-party audit reports.
|
||||
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| **Release** | **Reports** |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| Exchange V4 | We have an external audit scheduld with Consensys Diligence that will run from |
|
||||
| | November 30th - December 14th, 2020. |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| Exchange V3 | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`_ |
|
||||
| | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__ |
|
||||
| | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__ |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| Exchange V2.1 | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_ |
|
||||
| | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_ |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| MultiAssetProxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__ |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| ERC1155Proxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__ |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| StaticCallProxy | * No third-party audit. |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
||||
| ERC20BridgeProxy | * No third-party audit. |
|
||||
+------------------+---------------------------------------------------------------------------------------------------------------+
|
@ -1,3 +1,80 @@
|
||||
###############################
|
||||
Bounties
|
||||
###############################
|
||||
###############################
|
||||
|
||||
We run an ongoing bug bounty for the 0x Protocol smart contracts! The program is open to anyone and
|
||||
rewards up to **$100,000 for critical exploits**. The scope and disclosure instructions are below.
|
||||
|
||||
Rewards
|
||||
-------
|
||||
The severity of reported vulnerabilities will be graded according to the `CVSS <https://www.first.org/cvss/>`_ (Common Vulnerability Scoring Standard).
|
||||
The following table will serve as a guideline for reward decisions:
|
||||
|
||||
+----------------------------+---------------------+
|
||||
| **Exploit Score** | **Reward** |
|
||||
+----------------------------+---------------------+
|
||||
| Critical (CVSS 9.0 - 10.0) | $10,000 - $100,000 |
|
||||
+----------------------------+---------------------+
|
||||
| High (CVSS 7.0 - 8.9) | $2,500 - $10,000 |
|
||||
+----------------------------+---------------------+
|
||||
| Medium (CVSS 4.0 - 6.9) | $1,000 - $2,500 |
|
||||
+----------------------------+---------------------+
|
||||
| Low (CVSS 0.0 - 3.9) | $0 - $1,000 |
|
||||
+----------------------------+---------------------+
|
||||
|
||||
Please note that any rewards will ultimately be awarded at the discretion of ZeroEx Intl. All rewards will be paid out in ZRX.
|
||||
|
||||
Areas of Interest
|
||||
-----------------
|
||||
|
||||
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| **Area** | **Examples** |
|
||||
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Loss of funds | * A user loses funds in a way that they did not explicitly authorize (e.g an account is able to gain access to an ``AssetProxy`` and drain user funds). |
|
||||
| | * A user authorized a transaction or trade but spends more assets than normally expected (e.g an order is allowed to be over-filled). |
|
||||
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Unintended contract state | * A user is able to update the state of a contract such that it is no longer useable (e.g permanently lock a mutex). |
|
||||
| | * Any assets get unexpectedly "stuck" in a contract with regular use of the contract's public methods. |
|
||||
| | * An action taken in the staking contracts is applied to an incorrect epoch. |
|
||||
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Bypassing time locks | * The ``ZeroExGovernor`` is allowed to bypass the timelock for transactions where it is not explicitly allowed to do so. |
|
||||
| | * A user is allowed to bypass the ``ZeroExGovernor``. |
|
||||
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Incorrect math | * Overflows or underflow result in unexpected behavior. |
|
||||
| | * The staking reward payouts are incorrect. |
|
||||
+---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Scope
|
||||
-----
|
||||
The following contracts are in scope of the bug bounty. Please note that any bugs already reported are considered out of scope. See the `Audits <./audits.html>`_ page for 3rd party security reports.
|
||||
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| **Release** | **Contracts** | **Commit Hash** |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| Exchange V3 | * `ERC20BridgeProxy.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/asset-proxy/contracts/src/ERC20BridgeProxy.sol>`_ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/asset-proxy/erc20-bridge-proxy.md>`__) | `fb8360edfd <https://github.com/0xProject/0x-monorepo/tree/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts>`__|
|
||||
| | * `Exchange.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/exchange/contracts/src/Exchange.sol>`__ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md>`__) | |
|
||||
| | * `ZeroExGovernor.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/multisig/contracts/src/ZeroExGovernor.sol>`_ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/v3/zero-ex-governor.md>`__) | |
|
||||
| | * `Staking.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/staking/contracts/src/Staking.sol>`_ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/staking/staking-specification.md>`__) | |
|
||||
| | * `StakingProxy.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/staking/contracts/src/StakingProxy.sol>`_ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/staking/staking-specification.md>`__) | |
|
||||
| | * `ZrxVault.sol <https://github.com/0xProject/0x-monorepo/blob/fb8360edfd4f42f2d2b127b95c156eb1b0daa02b/contracts/staking/contracts/src/ZrxVault.sol>`_ (`spec <https://github.com/0xProject/0x-protocol-specification/blob/master/staking/staking-specification.md>`__) | |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| Exchange V2.1 | * `src/2.0.0/protocol <https://github.com/0xProject/0x-monorepo/tree/ff70c5ecfe28eff14e1a372c5e493b8f5363e1d0/packages/contracts/src/2.0.0/protocol>`_ | `ff70c5ecfe <https://github.com/0xProject/0x-monorepo/tree/ff70c5ecfe28eff14e1a372c5e493b8f5363e1d0/contracts>`_ |
|
||||
| | * `src/2.0.0/utils <https://github.com/0xProject/0x-monorepo/tree/ff70c5ecfe28eff14e1a372c5e493b8f5363e1d0/packages/contracts/src/2.0.0/utils>`_ | |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| MultiAssetProxy | * `MultiAssetProxy.sol <https://github.com/0xProject/0x-monorepo/blob/c4d9ef9f83508154fe9db35796b6b86aeb0f2240/contracts/asset-proxy/contracts/src/MultiAssetProxy.sol>`_ | `c4d9ef9f83 <https://github.com/0xProject/0x-monorepo/tree/c4d9ef9f83508154fe9db35796b6b86aeb0f2240/contracts>`_ |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| ERC1155Proxy | * `ERC1155Proxy.sol <https://github.com/0xProject/0x-monorepo/blob/77484dc69eea1f4f1a8397590199f3f2489751d2/contracts/asset-proxy/contracts/src/ERC1155Proxy.sol>`_ | `77484dc69e <https://github.com/0xProject/0x-monorepo/tree/77484dc69eea1f4f1a8397590199f3f2489751d2/contracts>`_ |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| StaticCallProxy | * `StaticCallProxy.sol <https://github.com/0xProject/0x-monorepo/blob/54f4727adc6da95f312e3721f44857110555d24c/contracts/asset-proxy/contracts/src/StaticCallProxy.sol>`_ | `54f4727adc <https://github.com/0xProject/0x-monorepo/tree/54f4727adc6da95f312e3721f44857110555d24c/contracts>`_ |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| ERC20BridgeProxy | * `ERC20BridgeProxy.sol <https://github.com/0xProject/0x-monorepo/blob/281658ba349a2c5088b40b503998bea5020284a6/contracts/asset-proxy/contracts/src/ERC20BridgeProxy.sol>`__ | `281658ba34 <https://github.com/0xProject/0x-monorepo/tree/281658ba349a2c5088b40b503998bea5020284a6/contracts>`_ |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
| ExchangeProxy | * `contracts/src <https://github.com/0xProject/0x-monorepo/tree/7967a8416c76e34ff5a0a4eb80e7b33ff8c0e297/contracts/zero-ex>`__ | `7967a8416c <https://github.com/0xProject/0x-monorepo/tree/7967a8416c76e34ff5a0a4eb80e7b33ff8c0e297/contracts>`_ |
|
||||
+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Disclosures
|
||||
-----------
|
||||
Please e-mail all submissions to security@0x.org with the subject "BUG BOUNTY". Your submission
|
||||
should include any steps required to reproduce or exploit the vulnerability. Please allow time for
|
||||
the vulnerability to be fixed before discussing any findings publicly. After receiving a submission,
|
||||
we will contact you with expected timelines for a fix to be implemented.
|
@ -1,3 +1,11 @@
|
||||
###############################
|
||||
Contributing
|
||||
###############################
|
||||
###############################
|
||||
|
||||
We are an open source project and welcome contributions!
|
||||
|
||||
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>`_.
|
||||
|
||||
We're also hiring, see our open roles at `0x.org/jobs <https://0x.org/about/jobs>`_.
|
19
docs/additional/exceptional_erc20s.rst
Normal file
@ -0,0 +1,19 @@
|
||||
###############################
|
||||
Exceptional ERC20s
|
||||
###############################
|
||||
|
||||
Some ERC20s have unique behavior that may require extra handling. We document these here as they are discovered.
|
||||
|
||||
Assert vs Require
|
||||
-----------------
|
||||
These ERC20's use `assert` instead of `require`, which means that if the token reverts then (nearly) all
|
||||
of the gas from your transaction will be consumed. Specifically, you are left with 1/64 of the gas limit.
|
||||
Be mindful of this when implementing fallback logic; for example, if a call to `transferFrom` reverts then
|
||||
note you will only have 1/64 of the gas limit to handle the exception.
|
||||
|
||||
Known tokens:
|
||||
|
||||
- KNC
|
||||
- LINK
|
||||
- sUSD
|
||||
- USDT
|
26
docs/additional/releases.rst
Normal file
@ -0,0 +1,26 @@
|
||||
###############################
|
||||
Releases
|
||||
###############################
|
||||
|
||||
.. role:: strike
|
||||
:class: strike
|
||||
|
||||
This page outlines upcoming releases and expected changes.
|
||||
|
||||
+-------------+----------------------+-----------------------------------------+
|
||||
| **Release** | **Est Release Date** | **Status** |
|
||||
+-------------+----------------------+-----------------------------------------+
|
||||
| Tinker | TBA | In Audits |
|
||||
+-------------+----------------------+-----------------------------------------+
|
||||
|
||||
|
||||
Tinker (Official V4 Release)
|
||||
----------------------------
|
||||
|
||||
- Upgrade that transfer user funds to use allowances on the Proxy contract. Transfers will still fallback to the Allowance Target, but integrators will get reduced transaction costs from setting their allowance on the Proxy.. See more on the `Allowances Page <../basics/allowances.html>`_.
|
||||
- Deploy `LiquidityProviderFeature <../architecture/features.html>`_.
|
||||
- Deploy `NativeLiquidityFeature <../architecture/features.html>`_.
|
||||
- Deploy updated `FillQuoteTransformer <../architecture/transformers.html>`_, which can fill `V4 Orders <../basics/orders.html>`_. This transformer will no longer call Exchange V3.
|
||||
- Introduce `new events <../basics/events.html>`_.
|
||||
- Decommission `SignatureValidationFeature <../architecture/features.html>`_.
|
||||
- Decommission `TokenSpenderFeature <../architecture/features.html>`_.
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Aggregation
|
||||
###############################
|
@ -1,3 +1,178 @@
|
||||
###############################
|
||||
ERC20 Transformations
|
||||
###############################
|
||||
###############################
|
||||
|
||||
|
||||
The 0x Protocol is able to perform a variety of atomic transformations on ERC20 tokens, in addition to simply executing trades. This is made possible through composable smart contracts, called `Transformers <../architecture/transformers.html>`_. These trustless modules extend the core Exchange logic, enabling workflows like converting between ETH<>WETH or aggregating liquidity across DEX's. These operations can be combined with trade exeuction to create a seamlesss trading experience.
|
||||
|
||||
Anyone can run transformations using the ``transformERC20`` Exchange function.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Executes a series of transformations to convert an ERC20 `inputToken`
|
||||
/// to an ERC20 `outputToken`.
|
||||
/// @param inputToken The token being provided by the sender.
|
||||
/// If `0xeee...`, ETH is implied and should be provided with the call.`
|
||||
/// @param outputToken The token to be acquired by the sender.
|
||||
/// `0xeee...` implies ETH.
|
||||
/// @param inputTokenAmount The amount of `inputToken` to take from the sender.
|
||||
/// If set to `uint256(-1)`, the entire spendable balance of the taker
|
||||
/// will be solt.
|
||||
/// @param minOutputTokenAmount The minimum amount of `outputToken` the sender
|
||||
/// must receive for the entire transformation to succeed. If set to zero,
|
||||
/// the minimum output token transfer will not be asserted.
|
||||
/// @param transformations The transformations to execute on the token balance(s)
|
||||
/// in sequence.
|
||||
/// @return outputTokenAmount The amount of `outputToken` received by the sender.
|
||||
function transformERC20(
|
||||
IERC20TokenV06 inputToken,
|
||||
IERC20TokenV06 outputToken,
|
||||
uint256 inputTokenAmount,
|
||||
uint256 minOutputTokenAmount,
|
||||
Transformation[] memory transformations
|
||||
)
|
||||
public
|
||||
override
|
||||
payable
|
||||
returns (uint256 outputTokenAmount);
|
||||
|
||||
A Transformation is defined by a ``deploymentNonce`` (which identifies the contract that implements the transformation) and ``data`` for that contract.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Defines a transformation to run in `transformERC20()`.
|
||||
struct Transformation {
|
||||
// The deployment nonce for the transformer.
|
||||
// The address of the transformer contract will be derived from this
|
||||
// value.
|
||||
uint32 deploymentNonce;
|
||||
// Arbitrary data to pass to the transformer.
|
||||
bytes data;
|
||||
}
|
||||
|
||||
The transaction will revert if a transformation fails; the `inputTokenAmount` cannot be transferred from the sender; or the ``minOutputTokenAmount`` is not transferred to the sender. A single `TransformedERC20 <../basics/events.html#transformederc20>`_ event is be emitted upon successful execution of all transformations.
|
||||
|
||||
Liquidity Aggregation
|
||||
---------------------
|
||||
|
||||
Liquidity can be pulled from other Decentralized Exchanges (DEX) to supplement native liquidity (0x orders). This is currently used by 0x API to provide the aggregate the best prices across the entire DEX Ecosystem. Check out `https://matcha.xyz <https://matcha.xyz>`_ to see this in action!
|
||||
|
||||
Supported DEX's:
|
||||
|
||||
* Balancer
|
||||
* Curve
|
||||
* DoDo
|
||||
* Kyber
|
||||
* MStable
|
||||
* Mooniswap
|
||||
* Oasis
|
||||
* Shell
|
||||
* Sushiswap
|
||||
* Uniswap v1/v2
|
||||
|
||||
This transformation is implemented by the `FillQuoteTransformer <../architecture/transformers.html>`_ and has the ``deploymentNonce`` of ``5``. Abi-Encode the following struct to get the ``data``:
|
||||
|
||||
.. warning::
|
||||
An upgrade is pending to this transformation. This currently uses Exchange V3 Orders, but will soon be updated to use `V4 Orders <../basics/orders.html>`_. - 11/26/2020
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Transform data to ABI-encode and pass into `transform()`.
|
||||
struct TransformData {
|
||||
// Whether we are performing a market sell or buy.
|
||||
Side side;
|
||||
// The token being sold.
|
||||
// This should be an actual token, not the ETH pseudo-token.
|
||||
IERC20TokenV06 sellToken;
|
||||
// The token being bought.
|
||||
// This should be an actual token, not the ETH pseudo-token.
|
||||
IERC20TokenV06 buyToken;
|
||||
// The orders to fill.
|
||||
IExchange.Order[] orders;
|
||||
// Signatures for each respective order in `orders`.
|
||||
bytes[] signatures;
|
||||
// Maximum fill amount for each order. This may be shorter than the
|
||||
// number of orders, where missing entries will be treated as `uint256(-1)`.
|
||||
// For sells, this will be the maximum sell amount (taker asset).
|
||||
// For buys, this will be the maximum buy amount (maker asset).
|
||||
uint256[] maxOrderFillAmounts;
|
||||
// Amount of `sellToken` to sell or `buyToken` to buy.
|
||||
// For sells, this may be `uint256(-1)` to sell the entire balance of
|
||||
// `sellToken`.
|
||||
uint256 fillAmount;
|
||||
// Who to transfer unused protocol fees to.
|
||||
// May be a valid address or one of:
|
||||
// `address(0)`: Stay in flash wallet.
|
||||
// `address(1)`: Send to the taker.
|
||||
// `address(2)`: Send to the sender (caller of `transformERC20()`).
|
||||
address payable refundReceiver;
|
||||
// Required taker address for RFQT orders.
|
||||
// Null means any taker can fill it.
|
||||
address rfqtTakerAddress;
|
||||
}
|
||||
|
||||
This transformation currently executes a Market Sell or Market Buy on a series of `0x V3 Orders <https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md#orders>`_. The transaction will revert if the ``fillAmount`` is not reached; an individual order can fail without the entire transaction reverting. A `ProtocolFeeUnfunded <../basics/events.html#protocolfeeunfunded>`_ event will be emitted if an order failed to fill because the Taker did not send a sufficient protocol fee.
|
||||
|
||||
|
||||
WETH Wrapping
|
||||
-------------
|
||||
|
||||
This transformation is implemented by the `WethTransformer <../architecture/transformers.html>`_ and has the ``deploymentNonce`` of ``1``. Abi-Encode the following struct to get the ``data``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Transform data to ABI-encode and pass into `transform()`.
|
||||
struct TransformData {
|
||||
// The token to wrap/unwrap. Must be either ETH or WETH.
|
||||
IERC20TokenV06 token;
|
||||
// Amount of `token` to wrap or unwrap.
|
||||
// `uint(-1)` will unwrap the entire balance.
|
||||
uint256 amount;
|
||||
}
|
||||
|
||||
If the supplied token address is `WETH (etherToken) <../basics/addresses.html>`_ then the supplied WETH will be unwrapped to ``ETH``. If any other address is supplied the any ETH passed in will be wrapped into ``WETH``. No events are emitted by 0x during this transformation, although token contracts may have events. This will revert if ``allowances <../basics/allowances.html>_`` are not set or the available balance is less than ``amount``.
|
||||
|
||||
Affiliate Fees
|
||||
--------------
|
||||
|
||||
This transformation is implemented by the `AffiliateFeeTransformer <../architecture/transformers.html>`_ and has the ``deploymentNonce`` of ``3``. Abi-Encode the following struct to get the ``data``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Information for a single fee.
|
||||
struct TokenFee {
|
||||
// The token to transfer to `recipient`.
|
||||
IERC20TokenV06 token;
|
||||
// Amount of each `token` to transfer to `recipient`.
|
||||
// If `amount == uint256(-1)`, the entire balance of `token` will be
|
||||
// transferred.
|
||||
uint256 amount;
|
||||
// Recipient of `token`.
|
||||
address payable recipient;
|
||||
}
|
||||
|
||||
This pays the ``recipient`` in the ``amount`` of ``token`` specified. This can be used by integrators who wish to add an additional fee on top of 0x Orders. No events are emitted by 0x during this transformation, although token contracts may have events. This will revert if `allowances <../basics/allowances.html>`_ are not set or the available balance is less than ``amount``.
|
||||
|
||||
Pay Taker
|
||||
---------
|
||||
|
||||
This transformation is implemented by the `PayTakerTransformer <../architecture/transformers.html>`_ and has the ``deploymentNonce`` of ``2``. Abi-Encode the following struct to get the ``data``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Transform data to ABI-encode and pass into `transform()`.
|
||||
struct TransformData {
|
||||
// The tokens to transfer to the taker.
|
||||
IERC20TokenV06[] tokens;
|
||||
// Amount of each token in `tokens` to transfer to the taker.
|
||||
// `uint(-1)` will transfer the entire balance.
|
||||
uint256[] amounts;
|
||||
}
|
||||
|
||||
This pays the ``taker`` in the ``amounts`` of each ``tokens`` specified. This is generally run at the end of all other transformations. For example, if you've swapped the taker's ETH for WETH then executed a trade through `Liquidity Aggregation`_, this transformation will can transfer the final output token back to the Taker.
|
||||
|
||||
No events are emitted by 0x during this transformation, although token contracts may have events. This will revert if `allowances <../basics/allowances.html>`_ are not set or the available balance is less than ``amount``.
|
||||
|
||||
Adding Custom Transformations
|
||||
-----------------------------
|
||||
Transformations are trustless, but at this time they are permissioned so only 0x Labs can deploy new Transformers. If you are interested in deploying your own transformation logic, please reach out to us on `Discord <https://discord.com/invite/d3FTX3M>`_.
|
232
docs/advanced/mtx.rst
Normal file
@ -0,0 +1,232 @@
|
||||
###############################
|
||||
Meta-Transactions
|
||||
###############################
|
||||
|
||||
Meta-Transactions are signed messages that instruct the 0x Protocol to run function(s) in the context of the signer. This signed mtx can then be shared off-chain, allowing anyone to execute on-chain. This is useful for integrators who would like to subsidize the Ethereum Gas Fee, or add custom smart contract logic to run atomically a fill. A signed meta-transaction can only be executed once.
|
||||
|
||||
A common use case for this is in Request For Quote (RFQ) systems. The Maker creates an order; the Taker signs a mtx permitting 0x Protocol to fill the order on their behalf; the mtx is returned to the Maker who submits it on-chain.
|
||||
|
||||
.. image:: ../_static/img/rfqm.png
|
||||
:alt: Meta-Transaction Example
|
||||
:align: center
|
||||
|
||||
|
||||
|
||||
Constructing
|
||||
============
|
||||
|
||||
To construct a Meta-Transaction, abi-encode the following struct and sign it.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Describes an exchange proxy meta transaction.
|
||||
struct MetaTransactionData {
|
||||
// Signer of meta-transaction. On whose behalf to execute the MTX.
|
||||
address payable signer;
|
||||
// Required sender, or NULL for anyone.
|
||||
address sender;
|
||||
// Minimum gas price.
|
||||
uint256 minGasPrice;
|
||||
// Maximum gas price.
|
||||
uint256 maxGasPrice;
|
||||
// MTX is invalid after this time.
|
||||
uint256 expirationTimeSeconds;
|
||||
// Nonce to make this MTX unique.
|
||||
uint256 salt;
|
||||
// Encoded call data to a function on the exchange proxy.
|
||||
bytes callData;
|
||||
// Amount of ETH to attach to the call.
|
||||
uint256 value;
|
||||
// ERC20 fee `signer` pays `sender`.
|
||||
IERC20TokenV06 feeToken;
|
||||
// ERC20 fee amount.
|
||||
uint256 feeAmount;
|
||||
}
|
||||
|
||||
The ``calldata`` field is specific to the function you wish to execute. At this time, the following functions are supported:
|
||||
|
||||
- `fillLimitOrder <../basics/functions.html#filllimitorder>`_
|
||||
- `fillRfqOrder <../basics/functions.html#fillrfqorder>`_
|
||||
- `transformERC20 <../advanced/erc20_transformations.html>`_
|
||||
|
||||
Signing
|
||||
=======
|
||||
|
||||
Meta-Transactions use the same signing technique as 0x Orders; see the `How to Sign <../basics/orders.html#how-to-sign>`_ section of the Orders documentation. See `getMetaTransactionHash`_ for generating a unique hash for your mtx.
|
||||
|
||||
Functionality
|
||||
=============
|
||||
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
| Function | Overview |
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
| `executeMetaTransaction`_ | Executes a single meta-transaction |
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
| `batchExecuteMetaTransactions`_ | Executes a batch of meta-transactions. |
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
| `getMetaTransactionExecutedBlock`_ | Returns the block that a meta-transaction was executed at. |
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
| `getMetaTransactionHashExecutedBlock`_ | Same as ``getMetaTransactionExecutedBlock``, only this function takes a meta-transaction hash. |
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
| `getMetaTransactionHash`_ | Returns the hash of a meta-transaction. |
|
||||
+----------------------------------------+------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
executeMetaTransaction
|
||||
----------------------
|
||||
|
||||
A single Meta-Transaction is executed by calling ``executeMetaTransaction``. A batch of mtx's can be executed by calling ``batchExecuteMetaTransactions``.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Execute a single meta-transaction.
|
||||
/// @param mtx The meta-transaction.
|
||||
/// @param signature The signature by `mtx.signer`.
|
||||
/// @return returnResult The ABI-encoded result of the underlying call.
|
||||
function executeMetaTransaction(
|
||||
MetaTransactionData calldata mtx,
|
||||
LibSignature.Signature calldata signature
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (bytes memory returnResult);
|
||||
|
||||
A `MetaTransactionExecuted <../basics/events.html#metatransactionexecuted>`_ event is emitted on succes. The ``returnResult`` contains the raw return data for the executed function. For example, if the function returns a ``uint256`` then the ``returnResult`` could be abi-decoded into a ``uint256``.
|
||||
|
||||
This call will revert in the following scenarios:
|
||||
|
||||
- The address in the ``mtx.sender`` field does not match ``msg.sender``.
|
||||
- The mtx has expired.
|
||||
- The Ethereum transaction's gas price (``tx.gasprice``) is outside of the range ``[mtx.minGasPrice..mtx.maxGasPrice]``
|
||||
- The ETH sent with the mtx is less than ``mtx.value``
|
||||
- The signature is invalid.
|
||||
- The mtx was already executed
|
||||
- The underlying function is not supported by meta-transactions (see list above).
|
||||
- The underlying function call reverts.
|
||||
|
||||
batchExecuteMetaTransactions
|
||||
----------------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Execute multiple meta-transactions.
|
||||
/// @param mtxs The meta-transactions.
|
||||
/// @param signatures The signature by each respective `mtx.signer`.
|
||||
/// @return returnResults The ABI-encoded results of the underlying calls.
|
||||
function batchExecuteMetaTransactions(
|
||||
MetaTransactionData[] calldata mtxs,
|
||||
LibSignature.Signature[] calldata signatures
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (bytes[] memory returnResults);
|
||||
|
||||
A `MetaTransactionExecuted <../basics/events.html#metatransactionexecuted>`_ event is emitted for each mtx on succes. The ``returnResult`` contains the raw return data for the executed function This call will revert if the one of the ``mtxs`` reverts.
|
||||
|
||||
|
||||
getMetaTransactionExecutedBlock
|
||||
-------------------------------
|
||||
|
||||
The ``block.number`` is stored on-chain when a mtx is executed. This value can be retrieved using the following function.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Get the block at which a meta-transaction has been executed.
|
||||
/// @param mtx The meta-transaction.
|
||||
/// @return blockNumber The block height when the meta-transactioin was executed.
|
||||
function getMetaTransactionExecutedBlock(MetaTransactionData calldata mtx)
|
||||
external
|
||||
view
|
||||
returns (uint256 blockNumber);
|
||||
|
||||
getMetaTransactionHashExecutedBlock
|
||||
-----------------------------------
|
||||
|
||||
This is a more gas-efficient implementation of ``getMetaTransactionExecutedBlock``.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Get the block at which a meta-transaction hash has been executed.
|
||||
/// @param mtxHash The meta-transaction hash.
|
||||
/// @return blockNumber The block height when the meta-transactioin was executed.
|
||||
function getMetaTransactionHashExecutedBlock(bytes32 mtxHash)
|
||||
external
|
||||
view
|
||||
returns (uint256 blockNumber);
|
||||
|
||||
|
||||
getMetaTransactionHash
|
||||
----------------------
|
||||
|
||||
The hash of the mtx is used to uniquely identify it inside the protocol. It is computed following the `EIP712 spec <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md>`_ standard. In solidity, the hash is computed using:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Get the EIP712 hash of a meta-transaction.
|
||||
/// @param mtx The meta-transaction.
|
||||
/// @return mtxHash The EIP712 hash of `mtx`.
|
||||
function getMetaTransactionHash(MetaTransactionData calldata mtx)
|
||||
external
|
||||
view
|
||||
returns (bytes32 mtxHash);
|
||||
|
||||
The simplest way to generate an order hash is by calling this function, ex:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = IZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF).getMetaTransactionHash(mtx);
|
||||
|
||||
The hash can be manually generated using the following code:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = keccak256(abi.encodePacked(
|
||||
'\x19\x01',
|
||||
// The domain separator.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 domain separator type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'EIP712Domain(',
|
||||
'string name,',
|
||||
'string version,',
|
||||
'uint256 chainId,',
|
||||
'address verifyingContract)'
|
||||
)),
|
||||
// The EIP712 domain separator values.
|
||||
'ZeroEx',
|
||||
'1.0.0',
|
||||
1, // For mainnet
|
||||
0xDef1C0ded9bec7F1a1670819833240f027b25EfF, // Address of the Exchange Proxy
|
||||
)),
|
||||
// The struct hash.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
"MetaTransactionData("
|
||||
"address signer,"
|
||||
"address sender,"
|
||||
"uint256 minGasPrice,"
|
||||
"uint256 maxGasPrice,"
|
||||
"uint256 expirationTimeSeconds,"
|
||||
"uint256 salt,"
|
||||
"bytes callData,"
|
||||
"uint256 value,"
|
||||
"address feeToken,"
|
||||
"uint256 feeAmount"
|
||||
")"
|
||||
)),
|
||||
// The struct values.
|
||||
mtx.signer,
|
||||
mtx.sender,
|
||||
mtx.minGasPrice,
|
||||
mtx.maxGasPrice,
|
||||
mtx.expirationTimeSeconds,
|
||||
mtx.salt,
|
||||
keccak256(mtx.callData),
|
||||
mtx.value,
|
||||
mtx.feeToken,
|
||||
mtx.feeAmount
|
||||
))
|
||||
));
|
||||
|
101
docs/advanced/plp.rst
Normal file
@ -0,0 +1,101 @@
|
||||
###############################
|
||||
Pluggable Liquidity (PLP)
|
||||
###############################
|
||||
|
||||
PLP (Pluggable Liquidity PLP) enables anyone to extend the 0x Protocol with their own on-chain liquidity provider, like an AMM (Automated Market Maker). Liquidity providers are sandboxed so their code can be totally closed-source; they are executed via the `LiquidityProviderFeature <../architecture/features.html>`_
|
||||
|
||||
|
||||
Implementing a Liquidity Provider
|
||||
=================================
|
||||
The only requirement is that the provider implements the interface in `ILiquidityProviderSandbox <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/external/ILiquidityProviderSandbox.sol>`_.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Calls `sellTokenForToken` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellTokenForToken(
|
||||
address provider,
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Calls `sellEthForToken` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellEthForToken(
|
||||
address provider,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Calls `sellTokenForEth` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of ETH to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellTokenForEth(
|
||||
address provider,
|
||||
address inputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external;
|
||||
|
||||
|
||||
Trading with a Liquidity Provider
|
||||
=================================
|
||||
|
||||
To trade with a liquidity provider use the ``sellToLiquidityProvider`` function.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Sells `sellAmount` of `inputToken` to the liquidity provider
|
||||
/// at the given `provider` address.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param provider The address of the on-chain liquidity provider
|
||||
/// to trade with.
|
||||
/// @param recipient The recipient of the bought tokens. If equal to
|
||||
/// address(0), `msg.sender` is assumed to be the recipient.
|
||||
/// @param sellAmount The amount of `inputToken` to sell.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to
|
||||
/// buy. Reverts if this amount is not satisfied.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
/// @return boughtAmount The amount of `outputToken` bought.
|
||||
function sellToLiquidityProvider(
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address payable provider,
|
||||
address recipient,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
override
|
||||
payable
|
||||
returns (uint256 boughtAmount);
|
||||
|
||||
This function transfers tokens from ``msg.sender`` to the liquidity provider then executes the trade through a sandboxed contract external to the Exchange Proxy. The sandbox then executes the trade through the provider. This function then transfers the output tokens to the ``recipient``.
|
||||
|
||||
This function will emit a `LiquidityProviderSwap <../basics/events.html#liquidityproviderswap>`_ event if the trade succeeds. It will revert if the amount of ``outputToken`` returned by the Liquidity Provider is less than ``minBuyAmount``.
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Private Liquidity Poools
|
||||
###############################
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Request for Quote
|
||||
###############################
|
30
docs/advanced/uniswap.rst
Normal file
@ -0,0 +1,30 @@
|
||||
###############################
|
||||
Optimized Uniswap Router
|
||||
###############################
|
||||
|
||||
The 0x Protocol is equipped with a highly optimized `UniswapV2 Router <https://uniswap.org/docs/v2/smart-contracts/router02/>`_, which can reduce the transaction cost of trading with Uniswap. Call the ``sellToUniswap`` function to execute a trade on Uniswap through the 0x Protocol.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Efficiently sell directly to uniswap/sushiswap.
|
||||
/// @param tokens Sell path.
|
||||
/// @param sellAmount of `tokens[0]` Amount to sell.
|
||||
/// @param minBuyAmount Minimum amount of `tokens[-1]` to buy.
|
||||
/// @param isSushi Use sushiswap if true.
|
||||
/// @return buyAmount Amount of `tokens[-1]` bought.
|
||||
function sellToUniswap(
|
||||
IERC20TokenV06[] calldata tokens,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
bool isSushi
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 buyAmount);
|
||||
|
||||
This function sells ``sellAmount`` of ``tokens[0]`` for at least ``minBuyAmount`` of ``tokens[-1]``. The ``tokens`` array defines how to route the trade between Uniswap pools. This function does not emit any events, although Uniswap pools will emit their own events. This function reverts if amount bought from Uniswap is less than ``minBuyAmount``, or if Uniswap reverts.
|
||||
|
||||
See the official `Uniswap V2 Documentation <https://uniswap.org/docs/v2/>`_ for information on events/reverts/allowances.
|
||||
|
||||
.. note::
|
||||
This function does not use allowances set on 0x. The ``msg.sender`` must have allowances set on Uniswap (or SushiSwap).
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
VIP Paths
|
||||
###############################
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
WETH Wrapping
|
||||
###############################
|
@ -1,3 +1,52 @@
|
||||
###############################
|
||||
Features
|
||||
###############################
|
||||
###############################
|
||||
|
||||
Features implement the core feature set of the 0x Protocol. They are trusted with user allowances and permissioned by the `0x Governor <./governor.html>`_. Features are run in the context of the `Proxy <../proxy.html>`_, via a ``delegatecall``.
|
||||
|
||||
Below is a catalog of Features.
|
||||
|
||||
.. table::
|
||||
:widths: 20 60 20
|
||||
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| **Feature** | **Description** | **Resources** |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| BootstrapFeature | Bootstraps the entire system. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/BootstrapFeature.sol>`__; `Usage <./proxy.html#bootstrapping>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| LiquidityProviderFeature | Connects the system to Pluggable Liquidity (PLP). | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/LiquidityProviderFeature.sol>`__; `Usage <../advanced/plp.html#trading-with-a-liquidity-provider>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| MetaTransactionsFeature | Executes Meta-Transactions. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol>`__; `Usage <../advanced/mtx.html>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| NativeLiquidityFeature | Functions for native 0x liquidity (see `Orders <../basics/orders.html>`_). | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol>`__; `Usage <../basics/functions.html>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| OwnableFeature | An implementation of Ownable that is compatible with the delegate-call proxy pattern. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/OwnableFeature.sol>`__; `Usage <./architecture/proxy.html#ownership>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| SignatureValidationFeature | *This feature is deprecated. Its code will be removed after the contract is decommissioned.* | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/SignatureValidatorFeature.sol>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| SimpleFunctionRegistry | Implements the registry of functions/features available in the system. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/SimpleFunctionRegistryFeature.sol>`__; `Usage <./proxy.html#function-registry>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| TokenSpenderFeature | *This feature is deprecated. Its code will be removed after the contract is decommissioned.* | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/TokenSpenderFeature.sol>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| TransformERC20Feature | Executes `Transformers <./transformers.html>`_ to aggregate liquidity and operate on ERC20 tokens. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/TransformERC20Feature.sol>`__; `Usage <../advanced/erc20_transformations.html>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| UniswapFeature | A highly-optimized UniswapV2 router; used to source liquidity from Uniswap. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/UniswapFeature.sol>`__; `Usage <../advanced/uniswap.html>`__ |
|
||||
+----------------------------+----------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
Implementing a Feature
|
||||
======================
|
||||
The only requirement is that the Feature implements the interface in `IFeature <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/features/IFeature.sol>`_. Review the `Proxy Section <./proxy.html>`_ for details on how to write a smart contract that is compatible with our architecture (ex, how to properly manage state).
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Basic interface for a feature contract.
|
||||
interface IFeature {
|
||||
|
||||
// solhint-disable func-name-mixedcase
|
||||
|
||||
/// @dev The name of this feature set.
|
||||
function FEATURE_NAME() external view returns (string memory name);
|
||||
|
||||
/// @dev The version of this feature set.
|
||||
function FEATURE_VERSION() external view returns (uint256 version);
|
||||
}
|
17
docs/architecture/fee_collectors.rst
Normal file
@ -0,0 +1,17 @@
|
||||
###############################
|
||||
Fee Collectors
|
||||
###############################
|
||||
|
||||
The `Protocol Fees <../basics/protocol_fees.html>`_ are paid into special Fee Collector contracts at time-of-fill. There is one collector for each Staking Pool. The fees are paid in aggregate from the collector to the `Staking System <../tokenomics/staking.md>`_; this can happen at anytime, but is most optimal to run during finalization. This increases the cost of finalizing an epoch, but substantially reduces the transaction cost for takers executing trades.
|
||||
|
||||
Architecture
|
||||
============
|
||||
|
||||
1. There is one Fee Collector per staking pool. The fee collector serves as a repository for protocol fees attributed to a given pool. It automatically ``approve()s`` the staking contract so fees can be aggregated during finalization. It also contains functionality to convert ETH to WETH. Fee collectors are created using ``CREATE2``. This gives us predictable addresses.
|
||||
|
||||
2. When a `Limit Order <../basics/orders.html#limitorders>`_ is filled, the protocol fee is paid to the Fee Collector that corresponds to ``order.pool``.
|
||||
|
||||
3. The `transferProtocolFeesForPools() <../basics/functions.html#transferprotocolfeesforpools>` function can be called to transfer the fees for a set of pools from their respective Fee Collectors into the Staking system.
|
||||
|
||||
.. image:: ../_static/img/fee_collectors.png
|
||||
:align: center
|
@ -1,3 +1,47 @@
|
||||
###############################
|
||||
Flash Wallet
|
||||
###############################
|
||||
###############################
|
||||
|
||||
The Flash Wallet is a sandboxed escrow contract that holds funds for `Transformers <./transformers.html>`_ to operate on. A `Feature <./features.html>`_ contract transfers tokens to the Flash Wallet, which then delegate call's into a Transformer to run operations on the escrowed funds. Transformers are trustless and therefore only have access to the funds deposted into the Flash Wallet; they do not have access to user allowances.
|
||||
|
||||
The wallet is currently only used by the ``TransformERC20`` feature. It is deployed using the ``createTransformWallet()`` function on the feature, which is only callable by the owner/governor. This allows us to deploy a fresh wallet in case we somehow break the old one, like if we accidentally selfdestruct it or clobber its state.
|
||||
|
||||
.. note::
|
||||
The wallet is currently only used for ERC20 tokens, but can be extended to work with other standards, like ERC1155 and ERC223, by implementing the required fallbacks for those standards.
|
||||
|
||||
The Flash Wallet exposes two functions of interest: ``executeCall()`` and ``executeDelegateCall()``. The former executes a ``call`` and reverts if the callee reverts. The latter executes a ``delegatecall`` and reverts if the callee reverts.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Execute an arbitrary call. Only an authority can call this.
|
||||
/// @param target The call target.
|
||||
/// @param callData The call data.
|
||||
/// @param value Ether to attach to the call.
|
||||
/// @return resultData The data returned by the call.
|
||||
function executeCall(
|
||||
address payable target,
|
||||
bytes calldata callData,
|
||||
uint256 value
|
||||
)
|
||||
external
|
||||
payable
|
||||
override
|
||||
onlyOwner
|
||||
returns (bytes memory resultData);
|
||||
|
||||
/// @dev Execute an arbitrary delegatecall, in the context of this puppet.
|
||||
/// Only an authority can call this.
|
||||
/// @param target The call target.
|
||||
/// @param callData The call data.
|
||||
/// @return resultData The data returned by the call.
|
||||
function executeDelegateCall(
|
||||
address payable target,
|
||||
bytes calldata callData
|
||||
)
|
||||
external
|
||||
payable
|
||||
override
|
||||
onlyOwner
|
||||
returns (bytes memory resultData);
|
||||
|
||||
View the code for the Flash Wallet `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/external/FlashWallet.sol>`_.
|
90
docs/architecture/governor.rst
Normal file
@ -0,0 +1,90 @@
|
||||
###############################
|
||||
Governor
|
||||
###############################
|
||||
|
||||
.. note::
|
||||
|
||||
This page is tailored for Exchange V4. For information on governance over past exhcange versions, see `this specification <https://github.com/0xProject/0x-protocol-specification/blob/master/v3/zero-ex-governor.md>`_.
|
||||
|
||||
The ``ZeroExGovernor`` is a time-locked multi-signature wallet that has permission to perform administrative functions within the protocol. Functions are timelocked (see below). Many functions that can be used to mitigate damage in case of emergencies (for example, if a vulnerability is discovered that puts user funds at risk) do not have a timelock.
|
||||
|
||||
The ``ZeroExGovernor`` is able to perform the following functions within the protocol:
|
||||
|
||||
Managing Ownership
|
||||
==================
|
||||
|
||||
The ``ZeroExGovernor`` can transfer ownership of any contract for which it is the ``owner`` by calling the following function:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Transfers ownership to a new address.
|
||||
/// @param newOwner Address of the new owner.
|
||||
function transferOwnership(address newOwner)
|
||||
public;
|
||||
|
||||
Managing Authorizations
|
||||
=======================
|
||||
|
||||
The ``ZeroExGovernor`` can also manage authorizations all permissioned contracts in the Exchange and Staking systems. While the ``ZeroExGovernor`` itself is currently the only authorized address in these contracts, this feature can be used to allow new contracts to perform admin functions under different conditions in the future (such as with an on-chain token vote).
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Authorizes an address.
|
||||
/// @param target Address to authorize.
|
||||
function addAuthorizedAddress(address target)
|
||||
external;
|
||||
|
||||
/// @dev Removes authorizion of an address.
|
||||
/// @param target Address to remove authorization from.
|
||||
function removeAuthorizedAddress(address target)
|
||||
external;
|
||||
|
||||
/// @dev Removes authorizion of an address.
|
||||
/// @param target Address to remove authorization from.
|
||||
/// @param index Index of target in authorities array.
|
||||
function removeAuthorizedAddressAtIndex(
|
||||
address target,
|
||||
uint256 index
|
||||
)
|
||||
external;
|
||||
|
||||
|
||||
Administering Systems
|
||||
=======================
|
||||
|
||||
The governor owns all permissioned, trusted contracts under the 0x Protocol. Any ``onlyOwner`` function can be executed by the governor. The governor requires 2/3 signatures and is timelocked.
|
||||
|
||||
|
||||
Timelocks
|
||||
============
|
||||
Function timelocks are represented in days, where one day is equivalent to 86,400 seconds.
|
||||
|
||||
.. csv-table::
|
||||
:header: "Contract", "Function", "Selector", "Timelock"
|
||||
|
||||
AllowanceTarget, ``addAuthorizedAddress``, ``42f1181e``, 1 day
|
||||
AllowanceTarget, ``removeAuthorizedAddress``, ``70712939``, 0 days
|
||||
AllowanceTarget, ``removeAuthorizedAddressAtIndex``, ``9ad26744``, 0 days
|
||||
Governor, ``registerFunctionCall``, ``751ad560``, 1 day
|
||||
ExchangeProxy, ``extend``, ``6eb224cb``, 1 day
|
||||
ExchangeProxy, ``migrate``, ``261fe679``, 1 day
|
||||
ExchangeProxy, ``rollback``, ``9db64a40``, 0 days
|
||||
ExchangeProxy, ``setQuoteSigner``, ``<deprecation in progress>``, 1 day
|
||||
ExchangeProxy, ``setTransformerDeployer``, ``87c96419``, 1 day
|
||||
ExchangeProxy, ``transferOwnership``, ``f2fde38b``, 1 day
|
||||
StakingProxy, ``addExchangeAddress``, ``8a2e271a``, 14 days
|
||||
StakingProxy, ``removeExchangeAddress``, ``01e28d84``, 14 days
|
||||
StakingProxy, ``attachStakingContract``, ``66615d56``, 14 days
|
||||
StakingProxy, ``detachStakingContract``, ``37b006a6``, 14 days
|
||||
StakingProxy, ``setParams``, ``9c3ccc82``, 7 days
|
||||
StakingProxy, ``addAuthorizedAddress``, ``42f1181e``, 14 days
|
||||
StakingProxy, ``removeAuthorizedAddress``, ``70712939``, 14 days
|
||||
StakingProxy, ``removeAuthorizedAddressAtIndex``, ``9ad26744``, 14 days
|
||||
StakingProxy, ``transferOwnership``, ``f2fde38b``, 14 days
|
||||
ZrxVault, ``setStakingProxy``, ``6bf3f9e5``, 14 days
|
||||
ZrxVault, ``enterCatastrophicFailure``, ``c02e5a7f``, 0 days
|
||||
ZrxVault, ``setZrxProxy``, ``ca5b0218``, 14 days
|
||||
ZrxVault, ``addAuthorizedAddress``, ``42f1181e``, 14 days
|
||||
ZrxVault, ``removeAuthorizedAddress``, ``70712939``, 14 days
|
||||
ZrxVault, ``removeAuthorizedAddressAtIndex``, ``9ad26744``, 14 days
|
||||
ZrxVault, ``transferOwnership``, ``f2fde38b``, 14 days
|
@ -1,3 +1,36 @@
|
||||
###############################
|
||||
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 diagram below illustrates our system (click to enlarge).
|
||||
|
||||
.. image:: ../_static/img/architecture.png
|
||||
:scale: 70%
|
||||
|
||||
------------
|
||||
|
||||
The table below defines our smart contract nomenclature.
|
||||
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| **Term** | **Definition** |
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Proxy <./proxy.html>`_ | The point of entry into the system. This contract delegate-calls into Features. |
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Features <./features.html>`_ | These contracts implement the core feature set of the 0x Protocol. They are trusted with user allowances and permissioned by the 0x Governor. |
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `Transformers <./transformers.html>`_ | These contracts extend the core protocol. They are trustless and permissioned by the Transformer Deployer. |
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `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. |
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| `PLP Sandbox <./plp_sandbox.html>`_ | `PLP <../advanced/plp.html>`_ liquidity providers are called from this sandbox. |
|
||||
+-------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
14
docs/architecture/plp_sandbox.rst
Normal file
@ -0,0 +1,14 @@
|
||||
###############################
|
||||
PLP Sandbox
|
||||
###############################
|
||||
|
||||
`PLP <../advanced/plp.html>`_ are external, closed-source contracts that provide liquidity to the 0x Protocol. We want to limit the contracts called from the context of the `Proxy <./proxy.html>` contract because this contract has access to user funds. We must mitigate the attack vector where an ERC20 Token (or some other trusted contract) is passed in place of a legitimate PLP liquidity provider. We do this by routing trades through the PLP Sandbox.
|
||||
|
||||
The diagram below illustrates this workflow.
|
||||
|
||||
.. image:: ../_static/img/plp_sandbox.png
|
||||
:align: center
|
||||
|
||||
See the `PLP Section <../advanced/plp.html>`_ for usage. View the code for the PLP Sandbox is `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/external/LiquidityProviderSandbox.sol>`_.
|
||||
|
||||
|
@ -1,3 +1,249 @@
|
||||
###############################
|
||||
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 contract’s only responsibility is to route (delegate) calls to per-function implementation contracts through its fallback.
|
||||
|
||||
.. 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).
|
||||
|
||||
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%
|
||||
|
||||
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()``.
|
||||
|
||||
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.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// Register or replace a function.
|
||||
function extend(bytes4 selector, address impl)
|
||||
external
|
||||
onlyOwner;
|
||||
|
||||
Call ``rollback()`` to revert a function implementation to a prior version in its history.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// Roll back to a previousimplementation of a function.
|
||||
function rollback(bytes4 selector, address targetImpl)
|
||||
external
|
||||
onlyOwner;
|
||||
|
||||
Ownership
|
||||
=========
|
||||
Another Feature, ``InitialMigration``, bootstraps into the proxy is the Ownable feature. 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
|
||||
|
||||
// Change the owner of this contract.
|
||||
function transferOwnership(address newOwner)
|
||||
external
|
||||
onlyOwner;
|
||||
|
||||
// Get the owner of this contract.
|
||||
function getOwner()
|
||||
external
|
||||
view
|
||||
returns (address owner_);
|
||||
|
||||
Migrations
|
||||
==========
|
||||
Migrations are upgrade logic that run in the context of the proxy contract. To do this, the owner calls the ``migrate()`` function, provided by the ``Ownable`` Feature. This follows a similar sequence as the bootstrap process. Notably, it temporarily sets the owner of the contract to itself for the duration of the migration call, which allows the migrator to perform admin-level operations through other features, such as registering or rolling back new functions. Before exiting, the owner is set to the newOwner, which is passed in to the call.
|
||||
|
||||
One motivation for the existence of this function, as opposed to just having the make individual admin calls, is a shortcoming of the ZeroExGoverner contract, which is designed to perform one operation at a time, with no strict ordering of those operations.
|
||||
|
||||
This is a stripped down ``migrate()`` feature implementation:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
contract Ownable {
|
||||
|
||||
// Execute a migration function in the context of the proxy contract.
|
||||
function migrate(address target, bytes calldata data, address newOwner)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
// If the owner is already set to ourselves then we've reentered.
|
||||
require(OwnableStorage.owner != address(this));
|
||||
// Temporarily set the owner to ourselves.
|
||||
OwnableStorage.owner = address(this);
|
||||
|
||||
// Perform the migration.
|
||||
target.delegatecall(data);
|
||||
|
||||
// Set the new owner.
|
||||
OwnableStorage.owner = newOWner;
|
||||
}
|
||||
}
|
||||
|
||||
This is an example sequence of a migration (click to enlarge):
|
||||
|
||||
.. image:: ../_static/img/zero_ex_migrate.png
|
||||
:align: center
|
||||
:scale: 70%
|
||||
|
||||
Storage Buckets
|
||||
===============
|
||||
|
||||
Because feature functions get delegatecalled into, they all share the same execution context and, thus, state space. It’s critical that storage for each feature be compartmentalized from other features to avoid accidentally writing to the same slot. We solve this by strictly adhering to a storage bucket pattern for our feature contracts. This rule also extends to all inherited contracts/mixins.
|
||||
|
||||
Storage buckets are enabled by new language features in solidity 0.6, which allow us to rewrite a storage variable’s slot reference to a globally unique ID. These IDs are stored in an append-only enum defined in LibStorage, to enforce uniqueness. The true storage slot for a bucket is the feature’s storage ID multiplied by a large constant to prevent overlap between buckets.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
LibStorage {
|
||||
enum StorageId {
|
||||
MyFeature
|
||||
}
|
||||
|
||||
function getStorageSlot(StorageId id) internal pure returns (uint256) {
|
||||
return uint256(id) * 1e18;
|
||||
}
|
||||
}
|
||||
|
||||
LibMyFeatureStorage {
|
||||
// Storage layout for this feature.
|
||||
struct Storage {
|
||||
mapping(bytes32 => bytes) myData;
|
||||
}
|
||||
|
||||
// Get the storage bucket for this feature.
|
||||
function getStorage() internal view returns (Storage storage st) {
|
||||
uint256 slot = LibStorage.getStorageSlot(
|
||||
LibStorage.StorageId.MyFeature
|
||||
);
|
||||
assembly { st_slot := slot }
|
||||
}
|
||||
}
|
||||
|
||||
With the above pattern, writing to storage is simply:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
LibMyFeatureStorage.getStorage().myData[...] = ...
|
||||
|
||||
|
||||
Version Management
|
||||
==================
|
||||
|
||||
**Inspection**
|
||||
|
||||
This is a rolling release model, where every feature/function has its own version. All feature contracts (except Bootstrap because it’s ephemeral), implement the IFeature interface:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
interface IFeature {
|
||||
// The name of this feature set.
|
||||
function FEATURE_NAME() external view returns (string memory name);
|
||||
|
||||
// The version of this feature set.
|
||||
function FEATURE_VERSION() external view returns (uint256 version);
|
||||
}
|
||||
|
||||
So, to get the version of a function one could do ``IFeature(getFunctionImplementation(foo.selector)).FEATURE_VERSION``.
|
||||
|
||||
**Best Practices**
|
||||
|
||||
The registry is intentionally not prescriptive on how features should be migrated. But there are some general best practices we can follow to avoid harming users, and ourselves.
|
||||
|
||||
**Deprecation**
|
||||
|
||||
In general, unless a function has a vulnerability, we should keep it intact for the duration of the deprecation schedule. Afterwards, we can ultimately disable the function by either calling extend() with a null implementation or by calling rollback() to a null implementation.
|
||||
|
||||
**Patches**
|
||||
|
||||
These include bug-fixes, optimizations, or any other changes that preserve the intended behavior of the function. For these cases, we should upgrade the function in-place, i.e., using the same selector but changing the implementation contract, through extend().
|
||||
|
||||
**Vulnerabilities**
|
||||
|
||||
If a vulnerability is found in a live function, we should call rollback() immediately to reset it to a non-vulnerable implementation. Because rollback() is a separate function from extend(), it can be exempted from timelocks to allow a swift response.
|
||||
|
||||
**Upgrades**
|
||||
|
||||
These involve meaningful behavioral changes, such as new settlement logic, changes to the order format (or its interpretation), etc. These should always be registered under a new selector, which comes free if the arguments also change, to allow users the opportunity to opt-in to new behavior. If the upgrade is intended to replace an existing feature, the old version should follow a deprecation schedule, unless we’re confident no one is using it.
|
||||
|
||||
**Features used by Features**
|
||||
|
||||
Not all features are designed to be exclusively consumed by the public. We can have internal features by applying an onlySelf modifier to the function. We need to be mindful of another class of user: the contract itself. Avoiding missteps on this will require a combination of diligence and good regression test suites.
|
||||
|
||||
Known Risks
|
||||
===========
|
||||
|
||||
The extreme flexibility of this model means we have few built-in guardrails that more conventional architectures enjoy. To avoid pitfalls, we’ve established a few new patterns to follow during development, but the following areas will always need careful scrutiny during code reviews.
|
||||
|
||||
**Extended Attack Surface for Features**
|
||||
|
||||
Because features all run in the same execution context, they inherit potential vulnerabilities from other features. Some vulnerabilities may also arise from the interactions of separate features, which may not be obvious without examining the system as a whole. Reviewers will always need to be mindful of these scenarios and features should try to create as much isolation of responsibilities as possible.
|
||||
|
||||
**Storage Layout Risks**
|
||||
|
||||
All features registered to the proxy will run in the same storage context as the proxy itself. We employ a pattern of per-feature storage buckets (structs) with globally unique bucket slots to mitigate issues.
|
||||
|
||||
**Slot Overlap**
|
||||
|
||||
Every time we develop a new feature, an entry is appended to the ``LibStorage.StorageId`` enum, which is the bucket ID for the feature’s storage. This applies to the storage used by the proxy contract itself. When calculating the true slot for the storage bucket, this enum value is offset by ``1`` and bit shifted by ``128``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function getStorageSlot(StorageId id) internal pure returns (uint256) {
|
||||
return (uint256(id) + 1) << 128;
|
||||
}
|
||||
|
||||
|
||||
Given Solidity’s `storage layout rules <https://solidity.readthedocs.io/en/v0.6.6/miscellaneous.html)>`_, subsequent storage buckets should always be 2^128 slots apart, which means buckets can have 2^128 flattened inline fields before overlapping. While it’s not impossible for buckets to overlap with this pattern, it should be extremely unlikely if we follow it closely. Maps and arrays are not stored sequentially but should also be affected by their base slot value to make collisions unlikely.
|
||||
|
||||
**Inherited Storage**
|
||||
|
||||
A more insidious way to corrupt storage buckets is to have a feature unintentionally inherit from a mixin that has plain (non-bucketed) state variables, because the mixin can potentially read/write to slots shared by other buckets through them. To avoid this:
|
||||
|
||||
1. We prefix all feature-compatible mixins with “Fixin” (“Feature” + “Mixin”) and only allow contract inheritance from these.
|
||||
|
||||
2. Storage IDs are offset by 1 before computing the slot value. This means the first real storage bucket will actually start at slot 2^128, which gives us a safety buffer for these scenarios, since it’s unlikely a mixin would unintentionally access slots beyond 2^128.
|
||||
Shared Access to Storage
|
||||
|
||||
There is nothing stopping a feature from reaching into another feature’s storage bucket and reading/modifying it. Generally this pattern is discouraged but may be necessary in some cases, or may be preferable to save gas. This can create an implicit tight coupling between features and we need to take those interactions into account when upgrading the features that own those storage buckets.
|
||||
|
||||
**Restricted Functions and Privilege Escalation**
|
||||
|
||||
We will also be registering functions that have caller restrictions. Functions designed for internal use only will have an onlySelf modifier that asserts that ``msg.sender == address(this)``. The other class of restricted functions are owner-only functions, which have an ``onlyOwner`` modifier that asserts that the ``msg.sender == LibOwnableStorage.Storage.owner``.
|
||||
|
||||
The check on owner-only functions can be easily circumvented in a feature by directly overwriting ``LibOwnableStorage.Storage.owner`` with another address. If best practices and patterns are adhered to, doing so would involve deliberate and obvious effort and should be caught in reviews.
|
||||
|
||||
**Self-Destructing Features**
|
||||
|
||||
A feature contract with self-destruct logic must safeguard this code path to only be executed after the feature is deregistered, otherwise its registered functions will fail. In most cases this would just cause the feature to temporarily go dark until we could redeploy it. But it may leave the proxy in an unusable state if this occurs in the contract of a mission-critical feature, e.g., Ownable or SimpleFunctionRegistry (neither of which can self-destruct).
|
||||
|
||||
Features should also be careful that ``selfdestruct`` is never executed in the context of the proxy to avoid destroying the proxy itself.
|
||||
|
||||
**Allowances**
|
||||
|
||||
Although the proxy will not have access to the V3 asset proxies initially, early features will require taker allowances to be accessible to the proxy somehow. Instead of having the proxy contract itself be the allowance target, we intend on using a separate “Puppet” contract, callable only by the proxy contract. This creates a layer of separation between the proxy contract and allowances, so moving user funds is a much more deliberate action. In the event of a major vulnerability, the owner can simply detach the puppet contract from the proxy. This also avoids the situation where the proxy has lingering allowances if we decide grant it asset proxy authorization.
|
||||
|
||||
**Balances**
|
||||
|
||||
Inevitably, there will be features that will cause the Exchange Proxy to hold temporary balances (e.g., payable functions). Thus, it’s a good idea that no feature should cause the Exchange Proxy to hold a permanent balance of tokens or ether, since these balances can easily get mixed up with temporary balances.
|
64
docs/architecture/transformer_deployer.rst
Normal file
@ -0,0 +1,64 @@
|
||||
###############################
|
||||
Transformer Deployer
|
||||
###############################
|
||||
|
||||
`Transformers <./transformers.html>`_ need to be permissioned because they are executed in the context of the `Flash Wallet <./flash_wallet.html>`_. This means that a malicious Transformer could grief the protocol by destroying the Flash Wallet via ``selfdestruct``, so we need some way to authenticate that the Transformer is safe to use at runtime.
|
||||
|
||||
The Transformer Deployer ``create``'s all Transformers, and its deployment nonce is used to validate a Transformer at runtime. The deployer is owned by 0x Labs, so only we are able to deploy Transformers.
|
||||
|
||||
The deployer implements two functions: ``deploy()`` and ``kill()``. The former is used to deploy new Transformers; it will emit a `Deployed <../basics/events.html#deployed>`_ event (that includes the nonce) or reverts if it fails to ``create`` the Transformer. The ``kill()`` function is used to destroy deprecated Transformers; this emits a `Killed <../basics/events.html#killed>`_ event or reverts if the Transformer's ``die()`` function reverts. Note that we cannot verify a Transformer called ``selfdestruct`` in the ``kill`` function because this information is not available until after the transaction executes.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Deploy a new contract. Only callable by an authority.
|
||||
/// Any attached ETH will also be forwarded.
|
||||
function deploy(bytes memory bytecode)
|
||||
public
|
||||
payable
|
||||
onlyAuthorized
|
||||
returns (address deployedAddress);
|
||||
|
||||
/// @dev Call `die()` on a contract. Only callable by an authority.
|
||||
/// @param target The target contract to call `die()` on.
|
||||
/// @param ethRecipient The Recipient of any ETH locked in `target`.
|
||||
function kill(IKillable target, address payable ethRecipient)
|
||||
public
|
||||
onlyAuthorized;
|
||||
|
||||
View the code for the Transformer Deployer `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/external/TransformerDeployer.sol>`_.
|
||||
|
||||
|
||||
Permissionless Transfomer Deployer
|
||||
===================================
|
||||
|
||||
A permissionless deployer has been developed and can be seen `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/external/PermissionlessTransformerDeployer.sol>`_. This serves a similar function to the current delployer, only it is capable of validating the Transformer's bytecode before deploying. It does this by tracing the bytecode in search of reachable opcodes that could post a threat to the Flash Wallet.
|
||||
|
||||
The ``isDelegateCallSafe`` function performs this check. It will return ``false`` if any of the following opcodes are reachable: ``callcode``, ``delegatecall``, ``selfdestruct``, ``create``, ``create2``, ``sload``, ``sstore``.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Checks whether a given address is safe to be called via
|
||||
/// delegatecall. A contract is considered unsafe if it includes any
|
||||
/// of the following opcodes: CALLCODE, DELEGATECALL, SELFDESTRUCT,
|
||||
/// CREATE, CREATE2, SLOAD, and STORE. This code is adapted from
|
||||
/// https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/helpers/IndestructibleRegistry.sol
|
||||
/// @param target The address to check.
|
||||
/// @return True if the contract is considered safe for delegatecall.
|
||||
function isDelegateCallSafe(address target) public view returns (bool);
|
||||
|
||||
THe ``deploy`` function is similar to the existing Transformer Deployer, only it uses a user-provided nonce to deploy the Transformer.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Deploy a new contract. Any attached ETH will be forwarded.
|
||||
function deploy(bytes memory bytecode, bytes32 salt)
|
||||
public
|
||||
payable
|
||||
returns (address deployedAddress);
|
||||
|
||||
|
||||
Note that there is no ``kill`` function in this deployer.
|
||||
|
||||
View the code for the Permissionless Transformer Deployer `here <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/external/PermissionlessTransformerDeployer.sol>`_.
|
||||
|
||||
There is some overhead to switching over to this deployer, as the ``Flash Wallet <./flash_wallet.html>``_ would need to be redeployed and some integrators would need to update their code. Therefore, this will be put into production once there is community-demand for permissionless transformers. Reach out to us on `Discord <https://discord.com/invite/d3FTX3M>`_ if you'd like to deploy a Transformer!
|
@ -1,3 +1,52 @@
|
||||
###############################
|
||||
Transformers
|
||||
###############################
|
||||
###############################
|
||||
|
||||
Transformers extend the core protocol. They are trustless and permissioned by the `Transformer Deployer <./transformer_deployer.html>`_. A Transformer is identified by the nonce of the Transformer Deployer that corresponds to its address. These contracts are executed in the context of the `Flash Wallet <./flash_wallet.html>`_ (via ``delegatecall``).
|
||||
|
||||
Below is a catalog of Transformers.
|
||||
|
||||
.. table::
|
||||
:widths: 20 60 20
|
||||
|
||||
+--------------------------+------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| **Transformer** | **Description** | **Resources** |
|
||||
+--------------------------+------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| FillQuoteTransformer | Aggregates Liquidity across DEXs and Native 0x Orders. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/transformers/FillQuoteTransformer.sol>`__; `Usage <../advanced/erc20_transformations.html#liquidity-aggregation>`__ |
|
||||
+--------------------------+------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| WethTransformer | Wraps ETH into WETH (and unwraps) | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/transformers/WethTransformer.sol>`__; `Usage <../advanced/erc20_transformations.html#weth-wrapping>`__ |
|
||||
+--------------------------+------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| AffiliateFeesTransformer | Allows integrators to charge an affiliate fee when an order is filled by their platform. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/transformers/AffiliateFeeTransformer.sol>`__; `Usage <../advanced/erc20_transformations.html#affiliate-fees>`__ |
|
||||
+--------------------------+------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| PayTakerTransformer | Forwards funds in the Flash Wallet to the Taker. | `Code <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/transformers/PayTakerTransformer.sol>`__; `Usage <../advanced/erc20_transformations.html#pay-taker>`__ |
|
||||
+--------------------------+------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Implementing a Transformer
|
||||
==========================
|
||||
Transformers are currently used by the `TransformERC20Feature <./features.html>`_ to aggregate liquidity and perform operations on ERC20 tokens (ex, wrapping ETH). Your transformer should inherit from `Transformer Contract <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/transformers/Transformer.sol>`_ and implement the interface in `IERC20Transformer <https://github.com/0xProject/protocol/blob/development/contracts/zero-ex/contracts/src/transformers/IERC20Transformer.sol>`_.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// @dev A transformation callback used in `TransformERC20.transformERC20()`.
|
||||
interface IERC20Transformer {
|
||||
|
||||
/// @dev Context information to pass into `transform()` by `TransformERC20.transformERC20()`.
|
||||
struct TransformContext {
|
||||
// The caller of `TransformERC20.transformERC20()`.
|
||||
address payable sender;
|
||||
// taker The taker address, which may be distinct from `sender` in the case
|
||||
// meta-transactions.
|
||||
address payable taker;
|
||||
// Arbitrary data to pass to the transformer.
|
||||
bytes data;
|
||||
}
|
||||
|
||||
/// @dev Called from `TransformERC20.transformERC20()`. This will be
|
||||
/// delegatecalled in the context of the FlashWallet instance being used.
|
||||
/// @param context Context information.
|
||||
/// @return success The success bytes (`LibERC20Transformer.TRANSFORMER_SUCCESS`).
|
||||
function transform(TransformContext calldata context)
|
||||
external
|
||||
returns (bytes4 success);
|
||||
}
|
||||
|
53
docs/basics/addresses.rst
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
###############################
|
||||
Addresses
|
||||
###############################
|
||||
|
||||
.. note::
|
||||
This page is auto-generated. See the `contract-addresses <https://github.com/0xProject/protocol/blob/development/packages/contract-addresses/addresses.json>`_ package for an exhaustive list of contracts across all networks.
|
||||
|
||||
Exchange V4
|
||||
===================
|
||||
.. csv-table::
|
||||
|
||||
exchangeProxy, `0xdef1c0ded9bec7f1a1670819833240f027b25eff <https://etherscan.io/address//0xdef1c0ded9bec7f1a1670819833240f027b25eff>`_
|
||||
exchangeProxyAllowanceTarget, `0xf740b67da229f2f10bcbd38a7979992fcc71b8eb <https://etherscan.io/address//0xf740b67da229f2f10bcbd38a7979992fcc71b8eb>`_
|
||||
exchangeProxyFlashWallet, `0x22f9dcf4647084d6c31b2765f6910cd85c178c18 <https://etherscan.io/address//0x22f9dcf4647084d6c31b2765f6910cd85c178c18>`_
|
||||
exchangeProxyGovernor, `0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e <https://etherscan.io/address//0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e>`_
|
||||
exchangeProxyLiquidityProviderSandbox, `0xdb971b18ea5075734cec1241732cc1b41031dfc9 <https://etherscan.io/address//0xdb971b18ea5075734cec1241732cc1b41031dfc9>`_
|
||||
exchangeProxyTransformerDeployer, `0x39dce47a67ad34344eab877eae3ef1fa2a1d50bb <https://etherscan.io/address//0x39dce47a67ad34344eab877eae3ef1fa2a1d50bb>`_
|
||||
|
||||
|
||||
|
||||
Transformers
|
||||
===================
|
||||
.. csv-table::
|
||||
|
||||
wethTransformer, `0x68c0bb685099dc7cb5c5ce2b26185945b357383e <https://etherscan.io/address//0x68c0bb685099dc7cb5c5ce2b26185945b357383e>`_
|
||||
payTakerTransformer, `0x49b9df2c58491764cf40cb052dd4243df63622c7 <https://etherscan.io/address//0x49b9df2c58491764cf40cb052dd4243df63622c7>`_
|
||||
fillQuoteTransformer, `0xfbfb26935f15db6a319a43db5085245a6df1e408 <https://etherscan.io/address//0xfbfb26935f15db6a319a43db5085245a6df1e408>`_
|
||||
affiliateFeeTransformer, `0x4581b59a05ba373b9f67676f66bdb5fcd67e7567 <https://etherscan.io/address//0x4581b59a05ba373b9f67676f66bdb5fcd67e7567>`_
|
||||
|
||||
|
||||
|
||||
ZRX / Staking
|
||||
===================
|
||||
.. csv-table::
|
||||
|
||||
staking, `0x2a17c35ff147b32f13f19f2e311446eeb02503f3 <https://etherscan.io/address//0x2a17c35ff147b32f13f19f2e311446eeb02503f3>`_
|
||||
stakingProxy, `0xa26e80e7dea86279c6d778d702cc413e6cffa777 <https://etherscan.io/address//0xa26e80e7dea86279c6d778d702cc413e6cffa777>`_
|
||||
zrxToken, `0xe41d2489571d322189246dafa5ebde1f4699f498 <https://etherscan.io/address//0xe41d2489571d322189246dafa5ebde1f4699f498>`_
|
||||
zrxVault, `0xba7f8b5fb1b19c1211c5d49550fcd149177a5eaf <https://etherscan.io/address//0xba7f8b5fb1b19c1211c5d49550fcd149177a5eaf>`_
|
||||
|
||||
|
||||
|
||||
Miscellaneous
|
||||
===================
|
||||
.. csv-table::
|
||||
|
||||
devUtils, `0x74134cf88b21383713e096a5ecf59e297dc7f547 <https://etherscan.io/address//0x74134cf88b21383713e096a5ecf59e297dc7f547>`_
|
||||
etherToken, `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 <https://etherscan.io/address//0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2>`_
|
||||
erc20BridgeSampler, `0xd8c38704c9937ea3312de29f824b4ad3450a5e61 <https://etherscan.io/address//0xd8c38704c9937ea3312de29f824b4ad3450a5e61>`_
|
||||
|
||||
|
||||
|
@ -5,8 +5,8 @@ Allowances
|
||||
.. _Allowance Target Address: https://github.com/0xProject/protocol/blob/development/packages/contract-addresses/addresses.json#L40
|
||||
|
||||
After the official release, allowances will be set directly on the Exchange V4 Proxy contract.
|
||||
Presently, while we are in beta, allowances should be set on the `Allowance Target Address`_.
|
||||
Presently, while we are in beta, allowances should be set on the `Allowance Target <./addresses.html#exchange-v4>`_.
|
||||
|
||||
The motivation for eliminating the separate Allowance Target in the official release is
|
||||
to reduce transaction costs. Depending on the operational overhead for our integrators,
|
||||
we may support allowances on both the Exchange V4 & the Allowance Target after the officual relase.
|
||||
we may support allowances on both the Exchange V4 & the Allowance Target after the official release, which is slated for January, 2021.
|
@ -1,3 +1,368 @@
|
||||
###############################
|
||||
Events
|
||||
###############################
|
||||
###############################
|
||||
|
||||
This is a complete catalogue of 0x events emitted when interacting with the Exchange Proxy system of contracts. The diagram below
|
||||
illustrates how events are emitted when trading through the Exchange Proxy.
|
||||
|
||||
.. warning::
|
||||
There are pending upgrades that impact these events. Please see the `Releases <../additional/releases.html>`_ page for more details.
|
||||
|
||||
|
||||
.. image:: ../_static/img/events.png
|
||||
:scale: 42%
|
||||
|
||||
|
||||
.. note::
|
||||
This catalogue does not include events emitted by tokens or other exchanges, like Uniswap. It also only lists 0x V3 events
|
||||
that are emitted during a Fill; for an extensive list of V3 events, see the `V3 Spec <https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md#events>`_.
|
||||
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| **Event** | **Description** | **Emitted By** |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `Deployed`_ | Emitted by the `Transformer Deployer <../architecture/transformer_deployer.html>`_ when a `Transformer <../architecture/transformers.html>`_ is deployed. | TransformerDeployer |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `ERC20BridgeTransfer`_ | Emitted when a trade occurs. | FlashWallet |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `Fill`_ | Emitted by Exchange V3 when an order is filled. | Exchange V3 |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `Killed`_ | Emitted by the `Transformer Deployer <../architecture/transformer_deployer.html>`_ when a `Transformer <../architecture/transformers.html>`_ is killed. | TransformerDeployer |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `MetaTransactionExecuted`_ | Emitted when a meta-transaction is executed on the Exchange Proxy. | ExchangeProxy |
|
||||
| | Note that this differs from meta-transactions that are executed on Exchange V3. | |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `Migrated`_ | Emitted when `ExchangeProxy.migrate()` is called. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `ProtocolFeeUnfunded`_ | Emitted when an order is skipped due to a lack of funds to pay the 0x Protocol fee. | FlashWallet |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `ProxyFunctionUpdated`_ | Emitted when a function is upgraded via `extend()` or `rollback()` | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `QuoteSignerUpdated`_ | Emitted when `ExchangeProxy.setQuoteSigner()` is called. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `TransformedERC20`_ | Emitted when an `ERC20 Transformation <../advanced/erc20_transformations.html>`_ completes. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `TransformerDeployerUpdated`_ | Emitted when the Transformer Deployer is upgraded. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `TransformerMetadata`_ | A general, customizable event emitted that can be emitted by transformers as-needed. | FlashWallet |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| **Events in upcoming releases** |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `LimitOrderFilled`_ | Emitted when a `V4 Limit Order <./orders.html#limit-orders>`_ is filled. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `RfqOrderFilled`_ | Emitted when a `V4 RFQ Order <./orders.html#rfq-orders>`_ is filled. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `OrderCancelled`_ | Emitted when a V4 Limit or RFQ Order is cancelled. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `PairCancelledLimitOrders`_ | Emitted when a Market Pair is cancelled for Limit Orders (see `cancelPairLimitOrders <./functions.html#cancelpairlimitorders>`_). | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `PairCancelledRfqOrders`_ | Emitted when a Market Pair is cancelled for RFQ Orders (see `cancelPairRfqOrders <./functions.html#cancelpairrfqorders>`_). | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `RfqOrderOriginsAllowed`_ | Emitted when a tx.origin is added/removed for RFQ, via `registerAllowedRfqOrigins <./functions.html#registerallowedrfqorigins>`_ | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
| `LiquidityProviderSwap`_ | Emitted when a `PLP <../advanced/plp.html>`_ executes a swap. | ExchangeProxy |
|
||||
+-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+
|
||||
|
||||
Deployed
|
||||
--------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted when a contract is deployed via `deploy()`.
|
||||
/// @param deployedAddress The address of the deployed contract.
|
||||
/// @param nonce The deployment nonce.
|
||||
/// @param sender The caller of `deploy()`.
|
||||
event Deployed(address deployedAddress, uint256 nonce, address sender);
|
||||
|
||||
ERC20BridgeTransfer
|
||||
-------------------
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted when a trade occurs.
|
||||
/// @param inputToken The token the bridge is converting from.
|
||||
/// @param outputToken The token the bridge is converting to.
|
||||
/// @param inputTokenAmount Amount of input token.
|
||||
/// @param outputTokenAmount Amount of output token.
|
||||
/// @param from The bridge address, indicating the underlying source of the fill.
|
||||
/// @param to The `to` address, currrently `address(this)`
|
||||
event ERC20BridgeTransfer(
|
||||
IERC20TokenV06 inputToken,
|
||||
IERC20TokenV06 outputToken,
|
||||
uint256 inputTokenAmount,
|
||||
uint256 outputTokenAmount,
|
||||
address from,
|
||||
address to
|
||||
);
|
||||
|
||||
Fill
|
||||
----
|
||||
.. code-block:: solidity
|
||||
|
||||
event Fill(
|
||||
address indexed makerAddress, // Address that created the order.
|
||||
address indexed feeRecipientAddress, // Address that received fees.
|
||||
bytes makerAssetData, // Encoded data specific to makerAsset.
|
||||
bytes takerAssetData, // Encoded data specific to takerAsset.
|
||||
bytes makerFeeAssetData, // Encoded data specific to makerFeeAsset.
|
||||
bytes takerFeeAssetData, // Encoded data specific to takerFeeAsset.
|
||||
bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getTypedDataHash).
|
||||
address takerAddress, // Address that filled the order.
|
||||
address senderAddress, // Address that called the Exchange contract (msg.sender).
|
||||
uint256 makerAssetFilledAmount, // Amount of makerAsset sold by maker and bought by taker.
|
||||
uint256 takerAssetFilledAmount, // Amount of takerAsset sold by taker and bought by maker.
|
||||
uint256 makerFeePaid, // Amount of makerFeeAssetData paid to feeRecipient by maker.
|
||||
uint256 takerFeePaid, // Amount of takerFeeAssetData paid to feeRecipient by taker.
|
||||
uint256 protocolFeePaid // Amount of eth or weth paid to the staking contract.
|
||||
);
|
||||
|
||||
|
||||
Killed
|
||||
------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted when a contract is killed via `kill()`.
|
||||
/// @param target The address of the contract being killed..
|
||||
/// @param sender The caller of `kill()`.
|
||||
event Killed(address target, address sender);
|
||||
|
||||
LimitOrderFilled
|
||||
----------------
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted whenever a `LimitOrder` is filled.
|
||||
/// @param orderHash The canonical hash of the order.
|
||||
/// @param maker The maker of the order.
|
||||
/// @param taker The taker of the order.
|
||||
/// @param feeRecipient Fee recipient of the order.
|
||||
/// @param takerTokenFilledAmount How much taker token was filled.
|
||||
/// @param makerTokenFilledAmount How much maker token was filled.
|
||||
/// @param protocolFeePaid How much protocol fee was paid.
|
||||
/// @param pool The fee pool associated with this order.
|
||||
event LimitOrderFilled(
|
||||
bytes32 orderHash,
|
||||
address maker,
|
||||
address taker,
|
||||
address feeRecipient,
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint128 takerTokenFilledAmount,
|
||||
uint128 makerTokenFilledAmount,
|
||||
uint128 takerTokenFeeFilledAmount,
|
||||
uint256 protocolFeePaid,
|
||||
bytes32 pool
|
||||
);
|
||||
|
||||
|
||||
MetaTransactionExecuted
|
||||
-----------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted whenever a meta-transaction is executed via
|
||||
/// `executeMetaTransaction()` or `executeMetaTransactions()`.
|
||||
/// @param hash The meta-transaction hash.
|
||||
/// @param selector The selector of the function being executed.
|
||||
/// @param signer Who to execute the meta-transaction on behalf of.
|
||||
/// @param sender Who executed the meta-transaction.
|
||||
event MetaTransactionExecuted(
|
||||
bytes32 hash,
|
||||
bytes4 indexed selector,
|
||||
address signer,
|
||||
address sender
|
||||
);
|
||||
|
||||
LiquidityProviderSwap
|
||||
---------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
event LiquidityProviderSwap(
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
uint256 inputTokenAmount,
|
||||
uint256 outputTokenAmount,
|
||||
address provider,
|
||||
address recipient
|
||||
);
|
||||
|
||||
Migrated
|
||||
--------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted when `migrate()` is called.
|
||||
/// @param caller The caller of `migrate()`.
|
||||
/// @param migrator The migration contract.
|
||||
/// @param newOwner The address of the new owner.
|
||||
event Migrated(address caller, address migrator, address newOwner);
|
||||
|
||||
OrderCancelled
|
||||
--------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted whenever a limit or RFQ order is cancelled.
|
||||
/// @param orderHash The canonical hash of the order.
|
||||
/// @param maker The order maker.
|
||||
event OrderCancelled(
|
||||
bytes32 orderHash,
|
||||
address maker
|
||||
);
|
||||
|
||||
PairCancelledLimitOrders
|
||||
------------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted whenever limit or RFQ orders are cancelled by pair by a maker.
|
||||
/// @param maker The maker of the order.
|
||||
/// @param makerToken The maker token in a pair for the orders cancelled.
|
||||
/// @param takerToken The taker token in a pair for the orders cancelled.
|
||||
/// @param minValidSalt The new minimum valid salt an order with this pair must
|
||||
/// have.
|
||||
event PairCancelledLimitOrders(
|
||||
address maker,
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint256 minValidSalt
|
||||
);
|
||||
|
||||
PairCancelledRfqOrders
|
||||
------------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted whenever limit or RFQ orders are cancelled by pair by a maker.
|
||||
/// @param maker The maker of the order.
|
||||
/// @param makerToken The maker token in a pair for the orders cancelled.
|
||||
/// @param takerToken The taker token in a pair for the orders cancelled.
|
||||
/// @param minValidSalt The new minimum valid salt an order with this pair must
|
||||
/// have.
|
||||
event PairCancelledRfqOrders(
|
||||
address maker,
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint256 minValidSalt
|
||||
);
|
||||
|
||||
ProtocolFeeUnfunded
|
||||
-------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted when a trade is skipped due to a lack of funds
|
||||
/// to pay the 0x Protocol fee.
|
||||
/// @param orderHash The hash of the order that was skipped.
|
||||
event ProtocolFeeUnfunded(bytes32 orderHash);
|
||||
|
||||
ProxyFunctionUpdated
|
||||
--------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev A function implementation was updated via `extend()` or `rollback()`.
|
||||
/// @param selector The function selector.
|
||||
/// @param oldImpl The implementation contract address being replaced.
|
||||
/// @param newImpl The replacement implementation contract address.
|
||||
event ProxyFunctionUpdated(bytes4 indexed selector, address oldImpl, address newImpl);
|
||||
|
||||
QuoteSignerUpdated
|
||||
------------------
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Raised when `setQuoteSigner()` is called.
|
||||
/// @param quoteSigner The new quote signer.
|
||||
event QuoteSignerUpdated(address quoteSigner);
|
||||
|
||||
RfqOrderFilled
|
||||
--------------
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted whenever an `RfqOrder` is filled.
|
||||
/// @param orderHash The canonical hash of the order.
|
||||
/// @param maker The maker of the order.
|
||||
/// @param taker The taker of the order.
|
||||
/// @param takerTokenFilledAmount How much taker token was filled.
|
||||
/// @param makerTokenFilledAmount How much maker token was filled.
|
||||
/// @param pool The fee pool associated with this order.
|
||||
event RfqOrderFilled(
|
||||
bytes32 orderHash,
|
||||
address maker,
|
||||
address taker,
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint128 takerTokenFilledAmount,
|
||||
uint128 makerTokenFilledAmount,
|
||||
bytes32 pool
|
||||
);
|
||||
|
||||
RfqOrderOriginsAllowed
|
||||
-------------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Emitted when new addresses are allowed or disallowed to fill
|
||||
/// orders with a given txOrigin.
|
||||
/// @param origin The address doing the allowing.
|
||||
/// @param addrs The address being allowed/disallowed.
|
||||
/// @param allowed Indicates whether the address should be allowed.
|
||||
event RfqOrderOriginsAllowed(
|
||||
address origin,
|
||||
address[] addrs,
|
||||
bool allowed
|
||||
);
|
||||
|
||||
|
||||
TransformedERC20
|
||||
----------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Raised upon a successful `transformERC20`.
|
||||
/// @param taker The taker (caller) address.
|
||||
/// @param inputToken The token being provided by the taker.
|
||||
/// If `0xeee...`, ETH is implied and should be provided with the call.`
|
||||
/// @param outputToken The token to be acquired by the taker.
|
||||
/// `0xeee...` implies ETH.
|
||||
/// @param inputTokenAmount The amount of `inputToken` to take from the taker.
|
||||
/// @param outputTokenAmount The amount of `outputToken` received by the taker.
|
||||
event TransformedERC20(
|
||||
address indexed taker,
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
uint256 inputTokenAmount,
|
||||
uint256 outputTokenAmount
|
||||
);
|
||||
|
||||
TransformerDeployerUpdated
|
||||
--------------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Raised when `setTransformerDeployer()` is called.
|
||||
/// @param transformerDeployer The new deployer address.
|
||||
event TransformerDeployerUpdated(address transformerDeployer);
|
||||
|
||||
|
||||
TransformerMetadata
|
||||
-------------------
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev A transformer that just emits an event with an arbitrary byte payload.
|
||||
event TransformerMetadata(
|
||||
bytes32 callDataHash,
|
||||
address sender,
|
||||
address taker,
|
||||
bytes data
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,584 @@
|
||||
###############################
|
||||
Functions
|
||||
###############################
|
||||
Basic Functionality
|
||||
###############################
|
||||
|
||||
Below is a catalog of basic Exchange functionality. For more advanced usage, like meta-transactions and dex aggregation, see the Advanced section.
|
||||
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| **Limit Orders** | **Overview** |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `fillLimitOrder`_ | Fills a Limit Order up to the amount requested. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `fillOrKillLimitOrder`_ | Fills exactly the amount requested or reverts. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `cancelLimitOrder`_ | Cancels an order so that it can no longer be filled. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `batchCancelLimitOrders`_ | A batch call to `cancelLimitOrder`. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `cancelPairLimitOrders`_ | Cancels Limit orders in a specific market pair. |
|
||||
| | Ex: Cancel all Limit Orders selling WETH for USDC. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `batchCancelLimitPairOrders`_ | A batch call to `cancelLimitPairOrders`. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `getLimitOrderInfo`_ | Returns the state of a given order. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `getLimitOrderHash`_ | Returns the EIP-712 hash for an order. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| **RFQ Orders** | **Overview** |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `fillRfqOrder`_ | These are analogous to the above LimitOrder functions. |
|
||||
+---------------------------------+ |
|
||||
| `fillOrKillRfqOrder`_ | |
|
||||
+---------------------------------+ |
|
||||
| `cancelRfqOrder`_ | |
|
||||
+---------------------------------+ |
|
||||
| `batchCancelRfqOrders`_ | |
|
||||
+---------------------------------+ |
|
||||
| `cancelPairRfqOrders`_ | |
|
||||
+---------------------------------+ |
|
||||
| `batchCancelPairRfqOrders`_ | |
|
||||
+---------------------------------+ |
|
||||
| `getRfqOrderInfo`_ | |
|
||||
+---------------------------------+ |
|
||||
| `getRfqOrderHash`_ | |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `registerAllowedRfqOrigins`_ | Register tx.origin addresses that are allowed to fill an RFQ order. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| **Protocol Fees** | **Overview** |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `getProtocolFeeMultiplier`_ | Takers of limit orders pay a protocol fee of `Multiplier * tx.gasprice`. |
|
||||
| | This returns the `Multiplier`. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
| `transferProtocolFeesForPools`_ | Transfers protocol fees from escrow to the 0x Staking System. |
|
||||
| | This should be called near the end of each epoch. |
|
||||
+---------------------------------+--------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Limit Orders
|
||||
============
|
||||
These are the basic functions for using a `Limit Order <../basics/orders.html#limit-orders>`_.
|
||||
|
||||
fillLimitOrder
|
||||
--------------
|
||||
|
||||
Limit orders can be filled with the ``fillLimitOrder()`` or ``fillOrKillLimitOrder()`` functions on the Exchange Proxy. The address calling these function will be considered the "taker" of the order.
|
||||
|
||||
|
||||
``fillLimitOrder()`` fills a single limit order for **up to** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillLimitOrder(
|
||||
// The order
|
||||
LimitOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 takerTokenFillAmount, uint128 makerTokenFillAmount);
|
||||
|
||||
|
||||
If the trade is successful a `LimitOrderFilled <../basics/events.html#limitorderfilled>`_ will be emitted. This function reverts under any of the following conditions:
|
||||
|
||||
- The order is fully filled: taker amount sold greater or equal to ``order.takerAmount``.
|
||||
- The order has expired.
|
||||
- The order was cancelled.
|
||||
- The market pair (Ex, ``WETH/USDT``) was cancelled (``order.salt`` is less than the value passed to ``cancelPairLimitOrders``.
|
||||
- Either the maker or taker has an insufficient allowance/balance.
|
||||
- The order's ``taker`` field is non-zero and does not match the actual taker. This is ``msg.sender``, unless used with `meta-transactions <../advanced/mtx.rst>`_ in which case it is the signer.
|
||||
- The order's ``sender`` field is non-zero and does not match ``msg.sender``.
|
||||
- The maker's signature is invalid.
|
||||
- The order's ``takerTokenFeeAmount`` is non-zero but the fee cannot be paid due to insufficient allowance/balance.
|
||||
- Not enough ETH was sent with the transaction to cover the `Protocol Fee <../basics/protocol_fees.html>`_.
|
||||
|
||||
|
||||
fillOrKillLimitOrder
|
||||
--------------------
|
||||
|
||||
``fillOrKillLimitOrder()`` fills a single limit order for **exactly** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillOrKillLimitOrder(
|
||||
// The order
|
||||
LimitOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 makerTokenFillAmount);
|
||||
|
||||
If the trade is successful a `LimitOrderFilled <../basics/events.html#limitorderfilled>`_ will be emitted. This function reverts under any of the conditions outlined above for ``fillLimitOrder``. Additionally, it will revert if the amount filled is less than ``takerTokenFillAmount``.
|
||||
|
||||
cancelLimitOrder
|
||||
----------------
|
||||
|
||||
This function cancels a single limit order created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelLimitOrder(
|
||||
// The order
|
||||
LimitOrder calldata order
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event if the cancellation is successful. The call will revert if ``msg.sender != order.maker``.
|
||||
|
||||
batchCancelLimitOrders
|
||||
----------------------
|
||||
|
||||
This function cancels multiple limit orders created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelLimitOrders(
|
||||
// The orders
|
||||
LimitOrder[] calldata orders
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event for each order it cancels. The call will revert if ``msg.sender != order.maker`` for any of the orders.
|
||||
|
||||
cancelPairLimitOrders
|
||||
---------------------
|
||||
|
||||
This function cancels all limit orders created by the caller with with a maker and taker token pair and a ``salt`` field < the ``salt`` provided. Subsequent calls to this function with the same tokens must provide a ``salt`` >= the last call to succeed.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelPairRfqOrders(
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint256 salt;
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits a `PairCancelledLimitOrders <../basics/events.html#paircancelledlimitorders>`_ event, or reverts in one of the following scenarios:
|
||||
|
||||
- ``msg.sender != order.maker``
|
||||
- The ``salt`` parameter is ≤ to a previous ``salt``.
|
||||
|
||||
batchCancelLimitPairOrders
|
||||
--------------------------
|
||||
|
||||
This function performs multiple ``cancelLimitPairOrders()`` at once. Each respective index across arrays is equivalent to a single call.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelLimitPairOrders(
|
||||
address[] makerTokens,
|
||||
address[] takerTokens,
|
||||
uint256[] salts;
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits a `PairCancelledLimitOrders <../basics/events.html#paircancelledlimitorders>`_ event for each market pair it cancels. It reverts if any of the individual cancellations revert.
|
||||
|
||||
getLimitOrderInfo
|
||||
-----------------
|
||||
|
||||
The Exchange Proxy exposes a function ``getLimitOrderInfo()`` to query information about a limit order, such as its fillable state and how much it has been filled by.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
enum OrderStatus {
|
||||
INVALID,
|
||||
FILLABLE,
|
||||
FILLED,
|
||||
CANCELLED,
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
struct OrderInfo {
|
||||
// The order hash.
|
||||
bytes32 orderHash;
|
||||
// Current state of the order.
|
||||
OrderStatus status;
|
||||
// How much taker token has been filled in the order.
|
||||
uint128 takerTokenFilledAmount;
|
||||
}
|
||||
|
||||
function getLimitOrderInfo(
|
||||
// The order
|
||||
LimitOrder calldata order
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (OrderInfo memory orderInfo);
|
||||
|
||||
getLimitOrderHash
|
||||
-----------------
|
||||
|
||||
The hash of the order is used to uniquely identify an order inside the protocol. It is computed following the `EIP712 spec <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md>`_ standard. In solidity, the hash is computed as:
|
||||
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Get the canonical hash of a limit order.
|
||||
/// @param order The limit order.
|
||||
/// @return orderHash The order hash.
|
||||
function getLimitOrderHash(LibNativeOrder.LimitOrder calldata order)
|
||||
external
|
||||
view
|
||||
returns (bytes32 orderHash);
|
||||
|
||||
The simplest way to generate an order hash is by calling this function, ex:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = IZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF).getLimitOrderHash(order);
|
||||
|
||||
The hash can be manually generated using the following code:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = keccak256(abi.encodePacked(
|
||||
'\x19\x01',
|
||||
// The domain separator.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 domain separator type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'EIP712Domain(',
|
||||
'string name,',
|
||||
'string version,',
|
||||
'uint256 chainId,',
|
||||
'address verifyingContract)'
|
||||
)),
|
||||
// The EIP712 domain separator values.
|
||||
'ZeroEx',
|
||||
'1.0.0',
|
||||
1, // For mainnet
|
||||
0xDef1C0ded9bec7F1a1670819833240f027b25EfF, // Address of the Exchange Proxy
|
||||
)),
|
||||
// The struct hash.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'LimitOrder(',
|
||||
'address makerToken,',
|
||||
'address takerToken,',
|
||||
'uint128 makerAmount,',
|
||||
'uint128 takerAmount,',
|
||||
'uint128 takerTokenFeeAmount,',
|
||||
'address taker,',
|
||||
'address maker,',
|
||||
'address sender,',
|
||||
'address feeRecipient,',
|
||||
'bytes32 pool,',
|
||||
'uint64 expiry,',
|
||||
'uint256 salt)'
|
||||
)),
|
||||
// The struct values.
|
||||
order.makerToken,
|
||||
order.takerToken,
|
||||
order.makerAmount,
|
||||
order.takerAmount,
|
||||
order.takerTokenFeeAmount,
|
||||
order.maker,
|
||||
order.taker,
|
||||
order.sender,
|
||||
order.feeRecipient,
|
||||
order.pool,
|
||||
order.expiry,
|
||||
order.salt
|
||||
))
|
||||
));
|
||||
|
||||
|
||||
RFQ Orders
|
||||
==========
|
||||
|
||||
These are the basic functions for using an `RFQ Order <../basics/orders.html#rfq-orders>`_.
|
||||
|
||||
fillRfqOrder
|
||||
------------
|
||||
|
||||
RFQ orders can be filled with the ``fillRfqOrder()`` or ``fillOrKillRfqOrder()`` functions on the Exchange Proxy. The address calling this function will be considered the "taker" of the order.
|
||||
|
||||
``fillRfqOrder()`` fills a single RFQ order for **up to** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillRfqOrder(
|
||||
// The order
|
||||
RfqOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 takerTokenFillAmount, uint128 makerTokenFillAmount);
|
||||
|
||||
If the trade is successful a `RfqOrderFilled <../basics/events.html#rfqorderfilled>`_ will be emitted. This function reverts under any of the following conditions:
|
||||
|
||||
- The order is fully filled: taker amount sold greater or equal to ``order.takerAmount``.
|
||||
- The order has expired.
|
||||
- The order was cancelled.
|
||||
- The market pair (Ex, ``WETH/USDT``) was cancelled (``order.salt`` is less than the value passed to ``cancelPairLimitOrders``.
|
||||
- Either the maker or taker has an insufficient allowance/balance.
|
||||
- The order's ``taker`` field is non-zero and does not match the actual taker. This is ``msg.sender``, unless used with `meta-transactions <../advanced/mtx.rst>`_ in which case it is the signer.
|
||||
- The order's ``origin`` field is non-zero and does not match ``tx.origin`` or a valid origin (see `registerAllowedRfqOrigins <../basics/functions.html#id11>`_).
|
||||
- The maker's signature is invalid.
|
||||
|
||||
fillOrKillRfqOrder
|
||||
------------------
|
||||
|
||||
``fillOrKillRfqOrder()`` fills a single RFQ order for **exactly** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillOrKillRfqOrder(
|
||||
// The order
|
||||
RfqOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 makerTokenFillAmount);
|
||||
|
||||
If the trade is successful a `RfqOrderFilled <../basics/events.html#rfqorderfilled>`_ will be emitted. This function reverts under any of the conditions outlined above for ``fillRfqOrder``. Additionally, it will revert if the amount filled is less than ``takerTokenFillAmount``.
|
||||
|
||||
cancelRfqOrder
|
||||
--------------
|
||||
|
||||
Similar to limit orders, RFQ orders can be cancelled on-chain through a variety of functions, which can only be called by the order's maker.
|
||||
|
||||
``cancelRfqOrder()`` cancels a single RFQ order created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelRfqOrder(
|
||||
// The order
|
||||
RfqOrder calldata order
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event if the cancellation is successful. The call will revert if ``msg.sender != order.maker``.
|
||||
|
||||
batchCancelRfqOrders
|
||||
--------------------
|
||||
|
||||
This function cancels multiple RFQ orders created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelRfqOrders(
|
||||
// The orders
|
||||
RfqOrder[] calldata orders
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event for each order it cancels. The call will revert if ``msg.sender != order.maker`` for any of the orders.
|
||||
|
||||
cancelPairRfqOrders
|
||||
-------------------
|
||||
|
||||
This function cancels all RFQ orders created by the caller with with a maker and taker token pair and a ``salt`` field < the ``salt`` provided. Subsequent calls to this function with the same tokens must provide a ``salt`` >= the last call to succeed.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelPairRfqOrders(
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint256 salt;
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits a `PairCancelledRfqOrders <../basics/events.html#paircancelledrfqorders>`_ event, or reverts in one of the following scenarios:
|
||||
|
||||
- ``msg.sender != order.maker``
|
||||
- The ``salt`` parameter is ≤ to a previous ``salt``.
|
||||
|
||||
batchCancelPairRfqOrders
|
||||
------------------------
|
||||
|
||||
``batchCancelPairRfqOrders()`` performs multiple ``cancelPairRfqOrders()`` at once. Each respective index across arrays is equivalent to a single call.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelPairRfqOrders(
|
||||
address[] makerTokens,
|
||||
address[] takerTokens,
|
||||
uint256[] salts;
|
||||
)
|
||||
external;
|
||||
|
||||
This function emits a `PairCancelledRfqOrders <../basics/events.html#paircancelledrfqorders>`_ event for each market pair it cancels. It reverts if any of the individual cancellations revert.
|
||||
|
||||
getRfqOrderInfo
|
||||
---------------
|
||||
|
||||
The Exchange Proxy exposes a function ``getRfqOrderInfo()`` to query information about an RFQ order, such as its fillable state and how much it has been filled by.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
enum OrderStatus {
|
||||
INVALID,
|
||||
FILLABLE,
|
||||
FILLED,
|
||||
CANCELLED,
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
struct OrderInfo {
|
||||
// The order hash.
|
||||
bytes32 orderHash;
|
||||
// Current state of the order.
|
||||
OrderStatus status;
|
||||
// How much taker token has been filled in the order.
|
||||
uint128 takerTokenFilledAmount;
|
||||
}
|
||||
|
||||
function getRfqOrderInfo(
|
||||
// The order
|
||||
RfqOrder calldata order
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (OrderInfo memory orderInfo);
|
||||
|
||||
getRfqOrderHash
|
||||
---------------
|
||||
|
||||
The hash of the order is used to uniquely identify an order inside the protocol. It is computed following the `EIP712 spec <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md>`_ standard. In solidity, the hash is computed using:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Get the canonical hash of an RFQ order.
|
||||
/// @param order The RFQ order.
|
||||
/// @return orderHash The order hash.
|
||||
function getRfqOrderHash(LibNativeOrder.RfqOrder calldata order)
|
||||
external
|
||||
view
|
||||
returns (bytes32 orderHash);
|
||||
|
||||
|
||||
The simplest way to generate an order hash is by calling this function, ex:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = IZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF).getRfqOrderHash(order);
|
||||
|
||||
The hash can be manually generated using the following code:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = keccak256(abi.encodePacked(
|
||||
'\x19\x01',
|
||||
// The domain separator.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 domain separator type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'EIP712Domain(',
|
||||
'string name,',
|
||||
'string version,',
|
||||
'uint256 chainId,',
|
||||
'address verifyingContract)'
|
||||
)),
|
||||
// The EIP712 domain separator values.
|
||||
'ZeroEx',
|
||||
'1.0.0',
|
||||
1, // For mainnet
|
||||
0xDef1C0ded9bec7F1a1670819833240f027b25EfF, // Address of the Exchange Proxy
|
||||
)),
|
||||
// The struct hash.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'RfqOrder(',
|
||||
'address makerToken,',
|
||||
'address takerToken,',
|
||||
'uint128 makerAmount,',
|
||||
'uint128 takerAmount,',
|
||||
'address maker,'
|
||||
'address taker,'
|
||||
'address txOrigin,'
|
||||
'bytes32 pool,',
|
||||
'uint64 expiry,',
|
||||
'uint256 salt)'
|
||||
)),
|
||||
// The struct values.
|
||||
order.makerToken,
|
||||
order.takerToken,
|
||||
order.makerAmount,
|
||||
order.takerAmount,
|
||||
order.maker,
|
||||
order.taker,
|
||||
order.txOrigin,
|
||||
order.pool,
|
||||
order.expiry,
|
||||
order.salt
|
||||
))
|
||||
));
|
||||
|
||||
registerAllowedRfqOrigins
|
||||
-------------------------
|
||||
|
||||
The RFQ order includes a ``txOrigin`` field, which a maker can use to restrict which EOA's can submit the Ethereum transaction that fills their order. There are two ways a maker can use this field.
|
||||
|
||||
1. Set to the EOA that will submit the transaction (ex, the Taker or a Meta-Transaction relayer).
|
||||
2. Set to an EOA owned by the maker, which acts as a registry key to lookup valid tx origins.
|
||||
|
||||
Looking at the 2nd use case, a maker can register valid tx origins using this function. They would then set ``order.origin`` to be the address they used to call ``registerAllowedRfqOrigins``.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Mark what tx.origin addresses are allowed to fill an order that
|
||||
/// specifies the message sender as its txOrigin.
|
||||
/// @param origins An array of origin addresses to update.
|
||||
/// @param allowed True to register, false to unregister.
|
||||
function registerAllowedRfqOrigins(address[] memory origins, bool allowed)
|
||||
external;
|
||||
|
||||
This function emits a `RfqOrderOriginsAllowed <../basics/events.html#rfqorderoriginsallowed>`_ event.
|
||||
|
||||
|
||||
Protocol Fees
|
||||
=============
|
||||
|
||||
There is a fixed protocol fee paid by the Taker each time they fill a `Limit Order <orders.html#limit-orders>`_. Learn more in the `Protocol Fees Section <./protocol_fees.html>`_. Also check out our research in the `Tokenomics Section <../tokenomics/research.html>`_.
|
||||
|
||||
getProtocolFeeMultiplier
|
||||
------------------------
|
||||
|
||||
Takers of limit orders pay a protocol fee of Multiplier * tx.gasprice. This returns the Multiplier.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Get the protocol fee multiplier. This should be multiplied by the
|
||||
/// gas price to arrive at the required protocol fee to fill a native order.
|
||||
/// @return multiplier The protocol fee multiplier.
|
||||
function getProtocolFeeMultiplier()
|
||||
external
|
||||
view
|
||||
returns (uint32 multiplier);
|
||||
|
||||
|
||||
transferProtocolFeesForPools
|
||||
----------------------------
|
||||
|
||||
This function transfers protocol fees from `Fee Collectors <../architecture/fee_collectors.html>`_ to the `Staking System <../tokenomics/staking.html>`_.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
/// @dev Transfers protocol fees from the `FeeCollector` pools into
|
||||
/// the staking contract.
|
||||
/// @param poolIds Staking pool IDs
|
||||
function transferProtocolFeesForPools(bytes32[] calldata poolIds)
|
||||
external;
|
@ -11,113 +11,88 @@ An order is a message passed into the 0x Protocol to facilitate an ERC20->ERC20
|
||||
Limit Orders
|
||||
==============
|
||||
|
||||
Limit orders are the standard 0x Order, which encodes a possible trade between a maker and taker at a fixed price. These orders are typically distributed via Mesh/SRA (open orderbook) or OTC, and can be filled through the ``fillOrder()`` function on the Exchange Proxy.
|
||||
|
||||
Structure
|
||||
---------
|
||||
Limit orders are the standard 0x Order, which encodes a possible trade between a maker and taker at a fixed price. These orders are typically distributed via Mesh/SRA (open orderbook) or OTC, and can be filled through the functions on the Exchange Proxy.
|
||||
|
||||
The ``LimitOrder`` struct has the following fields:
|
||||
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| Field | Type | Description |
|
||||
+==========================+=============+=============================================================================+
|
||||
| ``makerToken`` | ``address`` | The ERC20 token the maker is selling and the maker is selling to the taker. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``takerToken`` | ``address`` | The ERC20 token the taker is selling and the taker is selling to the maker. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``makerAmount`` | ``uint128`` | The amount of makerToken being sold by the maker. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``takerAmount`` | ``uint128`` | The amount of takerToken being sold by the taker. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``takerTokenFeeAmount`` | ``uint128`` | Amount of takerToken paid by the taker to the feeRecipient. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``maker`` | ``address`` | The address of the maker, and signer, of this order. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``taker`` | ``address`` | Allowed taker address. Set to zero to allow any taker. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``sender`` | ``address`` | Allowed address to directly call ``fillLimitOrder()`` (``msg.sender``). |
|
||||
| | | This is distinct from ``taker`` in meta-transactions. |
|
||||
| | | Set to zero to allow any caller. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``feeRecipient`` | ``address`` | Recipient of maker token or taker token fees (if non-zero). |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``pool`` | ``bytes32`` | The staking pool to attribute the 0x protocol fee from this order. |
|
||||
| | | Set to zero to attribute to the default pool, not owned by anyone. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``expiry`` | ``uint64`` | The Unix timestamp in seconds when this order expires. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``salt`` | ``uint256`` | Arbitrary number to enforce uniqueness of the order's hash. |
|
||||
+--------------------------+-------------+-----------------------------------------------------------------------------+
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| Field | Type | Description |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``makerToken`` | ``address`` | The ERC20 token the maker is selling and the maker is selling to the taker. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``takerToken`` | ``address`` | The ERC20 token the taker is selling and the taker is selling to the maker. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``makerAmount`` | ``uint128`` | The amount of makerToken being sold by the maker. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``takerAmount`` | ``uint128`` | The amount of takerToken being sold by the taker. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``takerTokenFeeAmount`` | ``uint128`` | Amount of takerToken paid by the taker to the feeRecipient. [optional; default 0] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``maker`` | ``address`` | The address of the maker, and signer, of this order. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``taker`` | ``address`` | Allowed taker address. Set to zero to allow any taker. [optional; default 0] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``sender`` | ``address`` | Allowed address to call ``fillLimitOrder()`` (``msg.sender``). |
|
||||
| | | This is the same as ``taker``, expect when using meta-transactions. |
|
||||
| | | Set to zero to allow any caller. [optional; default 0] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``feeRecipient`` | ``address`` | Recipient of maker token or taker token fees (if non-zero). [optional; default 0] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``pool`` | ``bytes32`` | The staking pool to attribute the 0x protocol fee from this order. |
|
||||
| | | Set to zero to attribute to the default pool, not owned by anyone. [optional; default 0] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``expiry`` | ``uint64`` | The Unix timestamp in seconds when this order expires. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
| ``salt`` | ``uint256`` | Arbitrary number to enforce uniqueness of the order hash. [required] |
|
||||
+-------------------------+-------------+------------------------------------------------------------------------------------------+
|
||||
|
||||
Hashing limit orders
|
||||
--------------------
|
||||
RFQ Orders
|
||||
==========
|
||||
|
||||
The hash of the order is used to uniquely identify an order inside the protocol. It is computed following the `EIP712 spec <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md>`_ standard. In solidity, the hash is computed as:
|
||||
RFQ orders are a stripped down version of standard limit orders, supporting fewer fields and a leaner settlement process.
|
||||
These orders are fielded just-in-time, directly from market makers, during the construction of a swap quote on 0x API,
|
||||
and can be filled through the ``fillRfqOrder()`` function on the Exchange Proxy.
|
||||
|
||||
.. code-block:: solidity
|
||||
Some notable differences from regular limit orders are:
|
||||
|
||||
bytes32 orderHash = keccak256(abi.encodePacked(
|
||||
'\x19\x01',
|
||||
// The domain separator.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 domain separator type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'EIP712Domain(',
|
||||
'string name,',
|
||||
'string version,',
|
||||
'uint256 chainId,',
|
||||
'address verifyingContract)'
|
||||
)),
|
||||
// The EIP712 domain separator values.
|
||||
'ZeroEx',
|
||||
'1.0.0',
|
||||
1, // For mainnet
|
||||
0xDef1C0ded9bec7F1a1670819833240f027b25EfF, // Address of the Exchange Proxy
|
||||
)),
|
||||
// The struct hash.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'LimitOrder(',
|
||||
'address makerToken,',
|
||||
'address takerToken,',
|
||||
'uint128 makerAmount,',
|
||||
'uint128 takerAmount,',
|
||||
'uint128 takerTokenFeeAmount,',
|
||||
'address taker,',
|
||||
'address maker,',
|
||||
'address sender,',
|
||||
'address feeRecipient,',
|
||||
'bytes32 pool,',
|
||||
'uint64 expiry,',
|
||||
'uint256 salt)'
|
||||
)),
|
||||
// The struct values.
|
||||
order.makerToken,
|
||||
order.takerToken,
|
||||
order.makerAmount,
|
||||
order.takerAmount,
|
||||
order.takerTokenFeeAmount,
|
||||
order.maker,
|
||||
order.taker,
|
||||
order.sender,
|
||||
order.feeRecipient,
|
||||
order.pool,
|
||||
order.expiry,
|
||||
order.salt
|
||||
))
|
||||
));
|
||||
* There is no ``sender`` field.
|
||||
* There is no taker fee.
|
||||
* Must restrict ``transaction.origin`` via the `order.txOrigin` field.
|
||||
* There is currently no protocol fee paid when filling an RFQ order.
|
||||
|
||||
Alternatively, the Exchange Proxy contract can be used to retrieve the hash given an order.
|
||||
The ``RFQOrder`` struct has the following fields:
|
||||
|
||||
.. code-block:: solidity
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Type | Description |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``makerToken`` | ``address`` | The ERC20 token the maker is selling and the maker is selling to the taker. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``takerToken`` | ``address`` | The ERC20 token the taker is selling and the taker is selling to the maker. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``makerAmount`` | ``uint128`` | The amount of makerToken being sold by the maker. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``takerAmount`` | ``uint128`` | The amount of takerToken being sold by the taker. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``maker`` | ``address`` | The address of the maker, and signer, of this order. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``taker`` | ``address`` | Allowed taker address. Set to zero to allow any taker. [optional; default 0] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``txOrigin`` | ``address`` | The allowed address of the EOA that submitted the Ethereum transaction. **This must be set**. |
|
||||
| | | Multiple addresses are supported via `registerAllowedRfqOrigins <./functions.html#registerallowedrfqorigins>`_. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``pool`` | ``bytes32`` | The staking pool to attribute the 0x protocol fee from this order. |
|
||||
| | | Set to zero to attribute to the default pool, not owned by anyone. [optional; default 0] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``expiry`` | ``uint64`` | The Unix timestamp in seconds when this order expires. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
| ``salt`` | ``uint256`` | Arbitrary number to enforce uniqueness of the order hash. [required] |
|
||||
+-----------------+-------------+----------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
bytes32 orderHash = IZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF).getLimitOrderHash(order);
|
||||
|
||||
Signing limit orders
|
||||
--------------------
|
||||
How To Sign
|
||||
==============
|
||||
|
||||
Limit orders must be signed by the maker of the order. This signature must be passed into the fill function by the taker in order to fill the order.
|
||||
Both Limit & RFQ orders must be signed by the `maker`. This signature is needed to fill an order, see `Basic Functionality <./functions.rst>`_.
|
||||
|
||||
The protocol accepts signatures defined by the following struct:
|
||||
|
||||
@ -137,10 +112,13 @@ There are two types of signatures supported: ``EIP712`` and ``EthSign``.
|
||||
|
||||
In both cases, the ``@0x/protocol-utils`` package simplifies generating these signatures.
|
||||
|
||||
.. note::
|
||||
The Protocol Utils package is still under development. This message will be removed once the package is published. - 11/24/2020.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const utils = require('@0x/protocol-utils');
|
||||
const order = new utils.LimitOrder({
|
||||
const order = new utils.LimitOrder({ // or utils.RfqOrder
|
||||
makerToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
|
||||
takerToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH
|
||||
... // Other fields
|
||||
@ -156,369 +134,7 @@ In both cases, the ``@0x/protocol-utils`` package simplifies generating these si
|
||||
makerAddress,
|
||||
);
|
||||
|
||||
Filling limit orders
|
||||
--------------------
|
||||
|
||||
Limit orders can be filled with the ``fillLimitOrder()`` or ``fillOrKillLimitOrder()`` functions on the Exchange Proxy. The address calling these function will be considered the "taker" of the order.
|
||||
|
||||
|
||||
``fillLimitOrder()`` fills a single limit order for **up to** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillLimitOrder(
|
||||
// The order
|
||||
LimitOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 takerTokenFillAmount, uint128 makerTokenFillAmount);
|
||||
|
||||
``fillOrKillLimitOrder()`` fills a single limit order for **exactly** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillOrKillLimitOrder(
|
||||
// The order
|
||||
LimitOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
payable
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 makerTokenFillAmount);
|
||||
|
||||
Cancelling a limit order
|
||||
------------------------
|
||||
|
||||
Because there is no way to un-sign an order that has been distributed, limit orders must be cancelled on-chain through one of several functions. They can only be called by the order's maker.
|
||||
|
||||
``cancelLimitOrder()`` cancels a single limit order created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelLimitOrder(
|
||||
// The order
|
||||
LimitOrder calldata order
|
||||
)
|
||||
external;
|
||||
|
||||
``batchCancelLimitOrders()`` cancels multiple limit orders created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelLimitOrders(
|
||||
// The orders
|
||||
LimitOrder[] calldata orders
|
||||
)
|
||||
external;
|
||||
|
||||
``cancelLimitPairOrders()`` will cancel all limit orders created by the caller with with a maker and taker token pair and a ``salt`` field < the ``salt`` provided. Subsequent calls to this function with the same tokens must provide a ``salt`` >= the last call to succeed.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelLimitPairLimitOrders(
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint256 salt;
|
||||
)
|
||||
external;
|
||||
|
||||
``batchCancelLimitPairOrders()`` performs multiple ``cancelLimitPairOrders()`` at once. Each respective index across arrays is equivalent to a single call.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelLimitPairOrders(
|
||||
address[] makerTokens,
|
||||
address[] takerTokens,
|
||||
uint256[] salts;
|
||||
)
|
||||
external;
|
||||
|
||||
Getting the status of a limit order
|
||||
-----------------------------------
|
||||
|
||||
The Exchange Proxy exposes a function ``getLimitOrderInfo()`` to query information about a limit order, such as its fillable state and how much it has been filled by.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
enum OrderStatus {
|
||||
INVALID,
|
||||
FILLABLE,
|
||||
FILLED,
|
||||
CANCELLED,
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
struct OrderInfo {
|
||||
// The order hash.
|
||||
bytes32 orderHash;
|
||||
// Current state of the order.
|
||||
OrderStatus status;
|
||||
// How much taker token has been filled in the order.
|
||||
uint128 takerTokenFilledAmount;
|
||||
}
|
||||
|
||||
function getLimitOrderInfo(
|
||||
// The order
|
||||
LimitOrder calldata order
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (OrderInfo memory orderInfo);
|
||||
|
||||
RFQ Orders
|
||||
==========
|
||||
|
||||
RFQ orders are a stripped down version of standard limit orders, supporting fewer fields and a leaner settlement process. These orders are fielded just-in-time, directly from market makers, during the construction of a swap quote on 0x API, and can be filled through the ``fillRfqOrder()`` function on the Exchange Proxy.
|
||||
|
||||
Some notable differences from regular limit orders are:
|
||||
|
||||
* The only fill restrictions that can be placed on an RFQ order is on the ``tx.origin`` and ``taker`` of the transaction.
|
||||
* There are no taker token fees.
|
||||
|
||||
Structure
|
||||
----------
|
||||
|
||||
The ``RFQOrder`` struct has the following fields:
|
||||
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| Field | Type | Description |
|
||||
+=================+=============+=============================================================================+
|
||||
| ``makerToken`` | ``address`` | The ERC20 token the maker is selling and the maker is selling to the taker. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``takerToken`` | ``address`` | The ERC20 token the taker is selling and the taker is selling to the maker. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``makerAmount`` | ``uint128`` | The amount of makerToken being sold by the maker. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``takerAmount`` | ``uint128`` | The amount of takerToken being sold by the taker. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``maker`` | ``address`` | The address of the maker, and signer, of this order. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``taker`` | ``address`` | Allowed taker address. Set to zero to allow any taker. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``txOrigin`` | ``address`` | The allowed address of the EOA that submitted the Ethereum transaction. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``pool`` | ``bytes32`` | The staking pool to attribute the 0x protocol fee from this order. |
|
||||
| | | Set to zero to attribute to the default pool, not owned by anyone. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``expiry`` | ``uint64`` | The Unix timestamp in seconds when this order expires. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
| ``salt`` | ``uint256`` | Arbitrary number to enforce uniqueness of the order's hash. |
|
||||
+-----------------+-------------+-----------------------------------------------------------------------------+
|
||||
|
||||
Hashing RFQ orders
|
||||
------------------
|
||||
|
||||
The hash of the order is used to uniquely identify an order inside the protocol. It is computed following the `EIP712 spec <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md>`_ standard. In solidity, the hash is computed as:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = keccak256(abi.encodePacked(
|
||||
'\x19\x01',
|
||||
// The domain separator.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 domain separator type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'EIP712Domain(',
|
||||
'string name,',
|
||||
'string version,',
|
||||
'uint256 chainId,',
|
||||
'address verifyingContract)'
|
||||
)),
|
||||
// The EIP712 domain separator values.
|
||||
'ZeroEx',
|
||||
'1.0.0',
|
||||
1, // For mainnet
|
||||
0xDef1C0ded9bec7F1a1670819833240f027b25EfF, // Address of the Exchange Proxy
|
||||
)),
|
||||
// The struct hash.
|
||||
keccak256(abi.encode(
|
||||
// The EIP712 type hash.
|
||||
keccak256(abi.encodePacked(
|
||||
'RfqOrder(',
|
||||
'address makerToken,',
|
||||
'address takerToken,',
|
||||
'uint128 makerAmount,',
|
||||
'uint128 takerAmount,',
|
||||
'address maker,'
|
||||
'address taker,'
|
||||
'address txOrigin,'
|
||||
'bytes32 pool,',
|
||||
'uint64 expiry,',
|
||||
'uint256 salt)'
|
||||
)),
|
||||
// The struct values.
|
||||
order.makerToken,
|
||||
order.takerToken,
|
||||
order.makerAmount,
|
||||
order.takerAmount,
|
||||
order.maker,
|
||||
order.taker,
|
||||
order.txOrigin,
|
||||
order.pool,
|
||||
order.expiry,
|
||||
order.salt
|
||||
))
|
||||
));
|
||||
|
||||
Alternatively, the Exchange Proxy contract can be used to retrieve the hash given an order.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
bytes32 orderHash = IZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF).getLimitOrderHash(order);
|
||||
|
||||
Signing RFQ orders
|
||||
------------------
|
||||
|
||||
RFQ orders must be signed by the maker of the order. This signature must be passed into the fill function by the taker in order to fill the order.
|
||||
|
||||
The protocol accepts signatures defined by the following struct:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
struct {
|
||||
uint8 v; // Signature data.
|
||||
bytes32 r; // Signature data.
|
||||
bytes32 s; // Signature data.
|
||||
}
|
||||
|
||||
The ``@0x/protocol-utils`` node package simplifies the process of creating a valid signature object.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const utils = require('@0x/protocol-utils');
|
||||
const order = new utils.RfqOrder({
|
||||
makerToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI
|
||||
takerToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH
|
||||
... // Other fields
|
||||
});
|
||||
// Generate an EthSign signature
|
||||
const signature = await order.ethSignHashWithProviderAsync(
|
||||
web3.currentProvider,
|
||||
makerAddress,
|
||||
);
|
||||
|
||||
Filling RFQ Orders
|
||||
------------------
|
||||
|
||||
RFQ orders can be filled with the ``fillRfqOrder()`` or ``fillOrKillRfqOrder()`` functions on the Exchange Proxy. The address calling this function will be considered the "taker" of the order.
|
||||
|
||||
``fillRfqOrder()`` fills a single RFQ order for **up to** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillRfqOrder(
|
||||
// The order
|
||||
RfqOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 takerTokenFillAmount, uint128 makerTokenFillAmount);
|
||||
|
||||
``fillOrKillRfqOrder()`` fills a single RFQ order for **exactly** ``takerTokenFillAmount``:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function fillOrKillRfqOrder(
|
||||
// The order
|
||||
RfqOrder calldata order,
|
||||
// The signature
|
||||
Signature calldata signature,
|
||||
// How much taker token to fill the order with
|
||||
uint128 takerTokenFillAmount
|
||||
)
|
||||
external
|
||||
// How much maker token from the order the taker received.
|
||||
returns (uint128 makerTokenFillAmount);
|
||||
|
||||
Cancelling an RFQ order
|
||||
-----------------------
|
||||
|
||||
Similar to limit orders, RFQ orders can be cancelled on-chain through a variety of functions, which can only be called by the order's maker.
|
||||
|
||||
``cancelRfqOrder()`` cancels a single RFQ order created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelRfqOrder(
|
||||
// The order
|
||||
RfqOrder calldata order
|
||||
)
|
||||
external;
|
||||
|
||||
``batchCancelRfqOrders()`` cancels multiple RFQ orders created by the caller:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelRfqOrders(
|
||||
// The orders
|
||||
RfqOrder[] calldata orders
|
||||
)
|
||||
external;
|
||||
|
||||
``cancelPairRfqOrders()`` will cancel all RFQ orders created by the caller with with a maker and taker token pair and a ``salt`` field < the ``salt`` provided. Subsequent calls to this function with the same tokens must provide a ``salt`` >= the last call to succeed.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function cancelPairRfqOrders(
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint256 salt;
|
||||
)
|
||||
external;
|
||||
|
||||
``batchCancelPairRfqOrders()`` performs multiple ``cancelPairRfqOrders()`` at once. Each respective index across arrays is equivalent to a single call.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function batchCancelPairRfqOrders(
|
||||
address[] makerTokens,
|
||||
address[] takerTokens,
|
||||
uint256[] salts;
|
||||
)
|
||||
external;
|
||||
|
||||
Getting the status of an RFQ order
|
||||
----------------------------------
|
||||
|
||||
The Exchange Proxy exposes a function ``getRfqOrderInfo()`` to query information about an RFQ order, such as its fillable state and how much it has been filled by.
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
enum OrderStatus {
|
||||
INVALID,
|
||||
FILLABLE,
|
||||
FILLED,
|
||||
CANCELLED,
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
struct OrderInfo {
|
||||
// The order hash.
|
||||
bytes32 orderHash;
|
||||
// Current state of the order.
|
||||
OrderStatus status;
|
||||
// How much taker token has been filled in the order.
|
||||
uint128 takerTokenFilledAmount;
|
||||
}
|
||||
|
||||
function getRfqOrderInfo(
|
||||
// The order
|
||||
RfqOrder calldata order
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (OrderInfo memory orderInfo);
|
||||
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.
|
18
docs/basics/protocol_fees.rst
Normal file
@ -0,0 +1,18 @@
|
||||
###############################
|
||||
Protocol Fees
|
||||
###############################
|
||||
|
||||
An ETH protocol fee is paid by the Taker each time a `Limit Order <./orders.html#limit-orders>`_ is `filled <./functions.html>`_.
|
||||
The fee is proportional to the gas cost of filling an order and scales linearly with gas price. The cost is currently ``70k * tx.gasprice``.
|
||||
Every 10 days, these fees are aggregated and distributed to the makers as a liquidity reward: the reward is proportional to the maker's collected fees and staked ZRX relative to other makers.
|
||||
To learn more about protocol fees and liquidity incentives, see the `Official Spec <https://github.com/0xProject/0x-protocol-specification/blob/master/staking/staking-specification.md>`_.
|
||||
|
||||
.. note::
|
||||
|
||||
`RFQ Orders <./orders.html#rfq-orders>`_ are introduced in Exchange V4, and there is currently no protocol fee for filling this type of order.
|
||||
The existing fee mechanics work well for limit orders, where arb bots pay to compete for liquidity; however, it does not translate well to RFQ where makers are matched with a specific taker.
|
||||
We are researching fee models that could be used for RFQ and will keep the community up-to-date on our `Forum <https://forum.0x.org/>`_.
|
||||
|
||||
.. warning::
|
||||
|
||||
In Exchange V3, protocol fees could be paid in ETH or WETH. As of V4, they can only be paid in ETH.
|
19
docs/conf.py
@ -14,6 +14,7 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import sphinx_rtd_theme
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
@ -28,7 +29,11 @@ import os
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['recommonmark']
|
||||
extensions = [
|
||||
'recommonmark',
|
||||
'sphinx_rtd_theme',
|
||||
'sphinx_markdown_tables',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@ -55,9 +60,9 @@ copyright = u'2016, ZeroEx Inc'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
version = '4.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0'
|
||||
release = '4.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@ -71,7 +76,7 @@ release = '1.0'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
exclude_patterns = ['_build', 'README.md', 'requirements.txt']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
@ -102,7 +107,7 @@ pygments_style = 'sphinx'
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
@ -139,6 +144,10 @@ html_context = {
|
||||
],
|
||||
}
|
||||
|
||||
html_js_files = [
|
||||
'js_overrides.js',
|
||||
]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
|
@ -1 +0,0 @@
|
||||
.. include:: ../CONTRIBUTING.rst
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Dummy
|
||||
###############################
|
@ -1 +0,0 @@
|
||||
.. include:: ../HISTORY.rst
|
@ -1,17 +1,17 @@
|
||||
0x Protocol
|
||||
===========
|
||||
|
||||
.. image:: logo.svg
|
||||
:width: 120px
|
||||
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>`_.
|
||||
|
||||
|
||||
.. image:: ./_static/img/logo.svg
|
||||
:width: 20%
|
||||
:alt: 0x Protocol logo
|
||||
:align: center
|
||||
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
:ref:`Keyword Index <genindex>`, :ref:`Search Page <search>`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Basics
|
||||
@ -20,16 +20,17 @@ Contents
|
||||
basics/functions.rst
|
||||
basics/events.rst
|
||||
basics/allowances.rst
|
||||
basics/protocol_fees.rst
|
||||
basics/addresses.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Advanced
|
||||
|
||||
advanced/mtx.rst
|
||||
advanced/erc20_transformations.rst
|
||||
advanced/aggregation.rst
|
||||
advanced/weth_wrapping.rst
|
||||
advanced/private_liquidity_pools.rst
|
||||
advanced/request_for_quote.rst
|
||||
advanced/plp.rst
|
||||
advanced/uniswap.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
@ -38,17 +39,22 @@ Contents
|
||||
architecture/overview.rst
|
||||
architecture/proxy.rst
|
||||
architecture/features.rst
|
||||
architecture/flash_wallet.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/protocol_fees.rst
|
||||
tokenomics/staking.rst
|
||||
tokenomics/research.rst
|
||||
tokenomics/staking.md
|
||||
tokenomics/staking_reward_formula.rst
|
||||
tokenomics/governance.rst
|
||||
tokenomics/voting.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
@ -57,12 +63,16 @@ Contents
|
||||
additional/audits.rst
|
||||
additional/bounties.rst
|
||||
additional/contributing.rst
|
||||
additional/exceptional_erc20s.rst
|
||||
additional/releases.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Connect
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
0x Labs <https://0x.org>
|
||||
GitHub <https://github.com/0xProject/protocol>
|
||||
Forum <https://forum.0x.org/>
|
||||
Reddit <https://www.reddit.com/r/0xProject/>
|
||||
Discord <https://discord.com/invite/d3FTX3M>
|
||||
Twitter <https://twitter.com/0xproject>
|
@ -1,7 +0,0 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
Install the package with pip::
|
||||
|
||||
$ pip install read-the-docs-template
|
@ -1 +0,0 @@
|
||||
.. include:: ../README.rst
|
2
docs/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
six
|
||||
sphinx-markdown-tables
|
84
docs/scripts/generate_addresses.py
Normal file
@ -0,0 +1,84 @@
|
||||
import json
|
||||
|
||||
####
|
||||
#### Run from `root/docs` directory. Generates `root/docs/basics/addresses.rst`
|
||||
####
|
||||
|
||||
|
||||
sections = [
|
||||
|
||||
# Exchange V4
|
||||
{
|
||||
"name": "Exchange V4",
|
||||
"contracts": [
|
||||
'exchangeProxy',
|
||||
'exchangeProxyAllowanceTarget',
|
||||
'exchangeProxyFlashWallet',
|
||||
'exchangeProxyGovernor',
|
||||
'exchangeProxyLiquidityProviderSandbox',
|
||||
'exchangeProxyTransformerDeployer'
|
||||
]
|
||||
},
|
||||
|
||||
# Exchange V4 transformers
|
||||
{
|
||||
"name": "Transformers",
|
||||
"contracts": [
|
||||
"transformers"
|
||||
]
|
||||
},
|
||||
|
||||
# ZRX / Staking
|
||||
{
|
||||
"name": "ZRX / Staking",
|
||||
"contracts": [
|
||||
'staking',
|
||||
'stakingProxy',
|
||||
'zrxToken',
|
||||
'zrxVault'
|
||||
]
|
||||
},
|
||||
|
||||
# Miscellaneous
|
||||
{
|
||||
"name": "Miscellaneous",
|
||||
"contracts": [
|
||||
'devUtils',
|
||||
'etherToken',
|
||||
'erc20BridgeSampler'
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
def printRow(contract, address):
|
||||
etherscanLink = "%s/%s"%("https://etherscan.io/address/", address)
|
||||
print(" %s, `%s <%s>`_"%(contract, address, etherscanLink))
|
||||
|
||||
def printTable(contracts, addresses):
|
||||
print(".. csv-table::\n")
|
||||
for contract in contracts:
|
||||
if isinstance(addresses[contract], unicode):
|
||||
printRow(contract, addresses[contract])
|
||||
else:
|
||||
for contract,address in addresses[contract].items():
|
||||
printRow(contract, address)
|
||||
|
||||
|
||||
print(
|
||||
'''
|
||||
###############################
|
||||
Addresses
|
||||
###############################
|
||||
|
||||
.. note::
|
||||
This page is auto-generated. See the `contract-addresses <https://github.com/0xProject/protocol/blob/development/packages/contract-addresses/addresses.json>`_ package for an exhaustive list of contracts across all networks.
|
||||
'''
|
||||
)
|
||||
|
||||
with open('../packages/contract-addresses/addresses.json') as f:
|
||||
addresses = json.load(f)
|
||||
for section in sections:
|
||||
print("%s\n==================="%(section["name"]))
|
||||
printTable(section["contracts"], addresses["1"])
|
||||
print("\n\n")
|
||||
|
@ -1,3 +1,5 @@
|
||||
###############################
|
||||
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!
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Protocol Fees
|
||||
###############################
|
9
docs/tokenomics/research.rst
Normal file
@ -0,0 +1,9 @@
|
||||
###############################
|
||||
Research
|
||||
###############################
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<embed>
|
||||
<iframe class="researchPdf" src="../_static/protocol-fees.pdf" width="100%" />
|
||||
</embed>
|
1484
docs/tokenomics/staking.md
Normal file
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Staking
|
||||
###############################
|
9
docs/tokenomics/staking_reward_formula.rst
Normal file
@ -0,0 +1,9 @@
|
||||
###############################
|
||||
Staking Reward Formula
|
||||
###############################
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<embed>
|
||||
<iframe class="researchPdf" src="../_static/adjusted-staking-percentage-formula.pdf" width="100%" />
|
||||
</embed>
|
@ -1,3 +0,0 @@
|
||||
###############################
|
||||
Voting
|
||||
###############################
|
@ -1,7 +0,0 @@
|
||||
========
|
||||
Usage
|
||||
========
|
||||
|
||||
To use this template, simply update it::
|
||||
|
||||
import read-the-docs-template
|