Compare commits
	
		
			214 Commits
		
	
	
		
			chore/bsc-
			...
			protocol@9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 9f5324d9c3 | ||
|  | 3647392a04 | ||
|  | 1d49662c58 | ||
|  | 6324b08b4d | ||
|  | fe73b63aaa | ||
|  | 192d0b17d9 | ||
|  | aa74d04083 | ||
|  | d586f5727d | ||
|  | 98fc79a085 | ||
|  | c12a10b96e | ||
|  | d3d4a08f91 | ||
|  | 9ce090c8cd | ||
|  | 980d60deb8 | ||
|  | d6d79e51e7 | ||
|  | 3ef5de93bb | ||
|  | ab7dc33ca4 | ||
|  | 14dcee5bb6 | ||
|  | 9856e78609 | ||
|  | 2801b066b3 | ||
|  | 5bc8b13fc3 | ||
|  | 36dba8f5be | ||
|  | ee2c069889 | ||
|  | 6ca14ed7b2 | ||
|  | a5babb9a34 | ||
|  | 661cc4669d | ||
|  | 553ba5c868 | ||
|  | d03d2f254d | ||
|  | feb91a04b0 | ||
|  | 4d63f33aba | ||
|  | b72b8b5ffd | ||
|  | f7cb7a0f51 | ||
|  | 9fcb28f5d8 | ||
|  | 982173471c | ||
|  | e77958425f | ||
|  | 6af4d71573 | ||
|  | ee985240fb | ||
|  | 2aadbda527 | ||
|  | 297c73abcc | ||
|  | 4c9e1b21ec | ||
|  | 41685d1545 | ||
|  | b9c25112ed | ||
|  | f0738fc122 | ||
|  | 42baf504b7 | ||
|  | 56038d122f | ||
|  | c4446b6c0e | ||
|  | eaed2958c3 | ||
|  | a045a3afb8 | ||
|  | 1cc59ab1ab | ||
|  | 2c6a714b71 | ||
|  | d8c97d6720 | ||
|  | d6bc702550 | ||
|  | 2838cb9420 | ||
|  | b10cfc50d3 | ||
|  | 2e6317b01e | ||
|  | 50e99e6eac | ||
|  | 8f2f4554eb | ||
|  | 67d9678a3a | ||
|  | f70341fb48 | ||
|  | 14cd24ea47 | ||
|  | 78328056d7 | ||
|  | 0045a60b0f | ||
|  | e4e71c76e1 | ||
|  | ca8127545f | ||
|  | 7b709089ce | ||
|  | 190f7e45f2 | ||
|  | 0dcc3a6fc3 | ||
|  | c2e8cae293 | ||
|  | 83da7caab4 | ||
|  | fd69a0c273 | ||
|  | 9b131199ad | ||
|  | f5c486050b | ||
|  | 1f41fe6a20 | ||
|  | 7f4080e0a2 | ||
|  | db76da58d7 | ||
|  | cf8fc0ff8e | ||
|  | 2d16f83e37 | ||
|  | 4057bdab91 | ||
|  | 1cd10f0ac9 | ||
|  | 68f87b2432 | ||
|  | 69bafc3bcd | ||
|  | 2c44b06b7b | ||
|  | 0233f00b4e | ||
|  | fedb53187d | ||
|  | 6774d2f588 | ||
|  | cf740b74f5 | ||
|  | 177c00463a | ||
|  | 49b0e32129 | ||
|  | 938fc94756 | ||
|  | 1561d91c2b | ||
|  | 9a28e51f51 | ||
|  | f55eaa867b | ||
|  | 6b2856424a | ||
|  | da757c4700 | ||
|  | 75e6654884 | ||
|  | 87308e7693 | ||
|  | d5eef93a76 | ||
|  | a7f23a982e | ||
|  | 9eadc5fc28 | ||
|  | 92ad1a612e | ||
|  | 09413c0e12 | ||
|  | 23788b41d5 | ||
|  | ccf999a495 | ||
|  | aa1016ee5f | ||
|  | 423ef57344 | ||
|  | c18149e82f | ||
|  | d14aebf724 | ||
|  | ba719a9631 | ||
|  | d36034d958 | ||
|  | 7750c57620 | ||
|  | 4d027e11d1 | ||
|  | 470e9a4697 | ||
|  | 7c51412e2f | ||
|  | b3d1f3cd10 | ||
|  | 389bb77439 | ||
|  | 4327885a00 | ||
|  | 0aef0afbbb | ||
|  | fa4c3a4f5f | ||
|  | 1d7c527c5c | ||
|  | cbe3135e4b | ||
|  | 955ad49711 | ||
|  | 8d6f6e76e0 | ||
|  | 9337115650 | ||
|  | fa45a44fe4 | ||
|  | c9c7ac8559 | ||
|  | c881723578 | ||
|  | c9c30d3a76 | ||
|  | 73dfdb5b69 | ||
|  | e638268f94 | ||
|  | 0bfd765481 | ||
|  | 1f12893735 | ||
|  | dd3d9337c4 | ||
|  | 904214f4a8 | ||
|  | 64c090c4b4 | ||
|  | e24474f152 | ||
|  | 29fa408256 | ||
|  | 1b94cc68af | ||
|  | f5b4bb3035 | ||
|  | afd880f28c | ||
|  | cd14cdd168 | ||
|  | c8ff53a75f | ||
|  | 6d08add20b | ||
|  | 29f9c725e3 | ||
|  | a83453f07f | ||
|  | ae365ce92c | ||
|  | 77a592e891 | ||
|  | 9a1df67d6b | ||
|  | 4b91411faf | ||
|  | 622a542d57 | ||
|  | cba53a9a50 | ||
|  | e186f27f63 | ||
|  | 4cd767ecb8 | ||
|  | f6e85aedf1 | ||
|  | b3ee294ba5 | ||
|  | 1c242def93 | ||
|  | f0fe6f2f69 | ||
|  | f86d555e49 | ||
|  | b0f2c40463 | ||
|  | 87be6fbb8a | ||
|  | 9141a9d2c8 | ||
|  | 7f75de347e | ||
|  | 329f7761c3 | ||
|  | 0d8e83cd75 | ||
|  | e5d60b8077 | ||
|  | ae2fe55efa | ||
|  | 6073607d3e | ||
|  | 389ebb5df8 | ||
|  | fd9655e9d4 | ||
|  | 6480aaa189 | ||
|  | 38969bb0a8 | ||
|  | 1847ab93af | ||
|  | c1177416f5 | ||
|  | 4fdd203211 | ||
|  | 4bc11776d7 | ||
|  | eb12eac5f3 | ||
|  | 5f5b951998 | ||
|  | 8e90547604 | ||
|  | fbea74d7ff | ||
|  | dcea16bc13 | ||
|  | d59a074bd7 | ||
|  | 39cc4f4dbf | ||
|  | 85bcf87af8 | ||
|  | a0fe1c610f | ||
|  | 5d21af1a0a | ||
|  | f6edbd210c | ||
|  | e084807a8f | ||
|  | 1c7d512829 | ||
|  | df0e0866e4 | ||
|  | 9e6efc3676 | ||
|  | 3aef29dace | ||
|  | 9a16e00577 | ||
|  | 84e4819e6e | ||
|  | 25dd6bc79a | ||
|  | 5d2cdb00c2 | ||
|  | 0f701f42d3 | ||
|  | 3e3e82d3f7 | ||
|  | c57bf86273 | ||
|  | f470d282ee | ||
|  | b8a2526da5 | ||
|  | 97575bbde9 | ||
|  | e5ed8b2c81 | ||
|  | 61fbae3ae2 | ||
|  | 5c2255c841 | ||
|  | e036dee6c5 | ||
|  | 8583aab241 | ||
|  | 5d05b62821 | ||
|  | 0063e8178f | ||
|  | ec6e5dd517 | ||
|  | 9d08fefa1c | ||
|  | 2fdca24d4e | ||
|  | 42ec0b144e | ||
|  | 3f6ce78b46 | ||
|  | c1300c1068 | ||
|  | 9a641cfab6 | ||
|  | 60345d4465 | 
| @@ -4,7 +4,7 @@ jobs: | |||||||
|     build: |     build: | ||||||
|         resource_class: xlarge |         resource_class: xlarge | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         environment: |         environment: | ||||||
|             NODE_OPTIONS: '--max-old-space-size=16384' |             NODE_OPTIONS: '--max-old-space-size=16384' | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
| @@ -19,7 +19,6 @@ jobs: | |||||||
|                   command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install |                   command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install | ||||||
|             - setup_remote_docker |             - setup_remote_docker | ||||||
|             - run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci |             - run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci | ||||||
|             - run: yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts |  | ||||||
|             - save_cache: |             - save_cache: | ||||||
|                   key: repo-{{ .Environment.CIRCLE_SHA1 }} |                   key: repo-{{ .Environment.CIRCLE_SHA1 }} | ||||||
|                   paths: |                   paths: | ||||||
| @@ -31,7 +30,7 @@ jobs: | |||||||
|     test-exchange-ganache: |     test-exchange-ganache: | ||||||
|         resource_class: medium+ |         resource_class: medium+ | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
| @@ -41,7 +40,7 @@ jobs: | |||||||
|     test-integrations-ganache: |     test-integrations-ganache: | ||||||
|         resource_class: medium+ |         resource_class: medium+ | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
| @@ -51,7 +50,7 @@ jobs: | |||||||
|     test-contracts-staking-ganache: |     test-contracts-staking-ganache: | ||||||
|         resource_class: medium+ |         resource_class: medium+ | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
| @@ -61,7 +60,7 @@ jobs: | |||||||
|     test-contracts-extra-ganache: |     test-contracts-extra-ganache: | ||||||
|         resource_class: medium+ |         resource_class: medium+ | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
| @@ -71,7 +70,7 @@ jobs: | |||||||
|     test-contracts-rest-ganache: |     test-contracts-rest-ganache: | ||||||
|         resource_class: medium+ |         resource_class: medium+ | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
| @@ -83,7 +82,7 @@ jobs: | |||||||
|         environment: |         environment: | ||||||
|             NODE_OPTIONS: '--max-old-space-size=6442' |             NODE_OPTIONS: '--max-old-space-size=6442' | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|             - image: 0xorg/verdaccio |             - image: 0xorg/verdaccio | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
| @@ -97,7 +96,7 @@ jobs: | |||||||
|                   path: ~/.npm/_logs |                   path: ~/.npm/_logs | ||||||
|     test-doc-generation: |     test-doc-generation: | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
| @@ -108,8 +107,10 @@ jobs: | |||||||
|                   no_output_timeout: 1200 |                   no_output_timeout: 1200 | ||||||
|     test-rest: |     test-rest: | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|  |         environment: | ||||||
|  |             RUST_ROUTER: 'true' | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
|                   keys: |                   keys: | ||||||
| @@ -117,7 +118,6 @@ jobs: | |||||||
|             - run: yarn wsrun -p @0x/contracts-test-utils -m --serial -c test:circleci |             - run: yarn wsrun -p @0x/contracts-test-utils -m --serial -c test:circleci | ||||||
|             - run: yarn wsrun -p @0x/contract-artifacts -m --serial -c test:circleci |             - run: yarn wsrun -p @0x/contract-artifacts -m --serial -c test:circleci | ||||||
|             - run: yarn wsrun -p @0x/contract-wrappers-test -m --serial -c test:circleci |             - run: yarn wsrun -p @0x/contract-wrappers-test -m --serial -c test:circleci | ||||||
|             - run: yarn wsrun -p @0x/migrations -m --serial -c test:circleci |  | ||||||
|             - run: yarn wsrun -p @0x/order-utils -m --serial -c test:circleci |             - run: yarn wsrun -p @0x/order-utils -m --serial -c test:circleci | ||||||
|             - run: yarn wsrun -p @0x/asset-swapper -m --serial -c test:circleci |             - run: yarn wsrun -p @0x/asset-swapper -m --serial -c test:circleci | ||||||
|             - save_cache: |             - save_cache: | ||||||
| @@ -136,7 +136,7 @@ jobs: | |||||||
|         resource_class: large |         resource_class: large | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
|                   keys: |                   keys: | ||||||
| @@ -147,7 +147,7 @@ jobs: | |||||||
|             - run: yarn diff_md_docs:ci |             - run: yarn diff_md_docs:ci | ||||||
|     submit-coverage: |     submit-coverage: | ||||||
|         docker: |         docker: | ||||||
|             - image: node:12 |             - image: node:16 | ||||||
|         working_directory: ~/repo |         working_directory: ~/repo | ||||||
|         steps: |         steps: | ||||||
|             - restore_cache: |             - restore_cache: | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,6 @@ | |||||||
| python: ['python-packages'] | python: ['python-packages'] | ||||||
| contracts: ['contracts'] | contracts: ['contracts'] | ||||||
| @0x/contract-addresses: ['packages/contract-addresses'] | @0x/contract-addresses: ['packages/contract-addresses'] | ||||||
| @0x/migrations: ['packages/migrations'] |  | ||||||
| @0x/order-utils: ['packages/order-utils'] | @0x/order-utils: ['packages/order-utils'] | ||||||
| @0x/contract-artifacts: ['packages/contract-artifacts'] | @0x/contract-artifacts: ['packages/contract-artifacts'] | ||||||
| @0x/contract-wrappers: ['packages/contract-wrappers'] | @0x/contract-wrappers: ['packages/contract-wrappers'] | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							| @@ -28,7 +28,7 @@ jobs: | |||||||
|                 fetch-depth: 0 |                 fetch-depth: 0 | ||||||
|             - uses: actions/setup-node@v1 |             - uses: actions/setup-node@v1 | ||||||
|               with: |               with: | ||||||
|                 node-version: 10 |                 node-version: 16 | ||||||
|             - uses: actions/setup-python@v2 |             - uses: actions/setup-python@v2 | ||||||
|             - name: 'configure git' |             - name: 'configure git' | ||||||
|               run: | |               run: | | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								CODEOWNERS
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CODEOWNERS
									
									
									
									
									
								
							| @@ -1,18 +1,20 @@ | |||||||
| # See https://help.github.com/articles/about-codeowners/ | # See https://help.github.com/articles/about-codeowners/ | ||||||
|  |  | ||||||
| # for more info about CODEOWNERS file | # for more info about CODEOWNERS file | ||||||
|  |  | ||||||
| # It uses the same pattern rule for gitignore file | # It uses the same pattern rule for gitignore file | ||||||
|  |  | ||||||
| # https://git-scm.com/docs/gitignore#_pattern_format | # https://git-scm.com/docs/gitignore#_pattern_format | ||||||
|  |  | ||||||
| # Website | packages/asset-swapper/ @dekz @dextracker @kyu-c | ||||||
| packages/asset-swapper/  @BMillman19 @fragosti @dave4506 |  | ||||||
| packages/instant/  @BMillman19 @fragosti @dave4506 |  | ||||||
|  |  | ||||||
| # Dev tools & setup | # Dev tools & setup | ||||||
| .circleci/ @dorothy-zbornak |  | ||||||
| packages/contract-addresses/ @abandeali1 | .circleci/ @dekz | ||||||
| packages/contract-artifacts/ @abandeali1 | packages/contract-addresses/ @dekz @dextracker @kyu-c | ||||||
| packages/order-utils/ @dorothy-zbornak  | packages/contract-artifacts/ @dekz | ||||||
|  | packages/protocol-utils/ @dekz | ||||||
|  |  | ||||||
| # Protocol/smart contracts | # Protocol/smart contracts | ||||||
| contracts/ @abandeali1 @hysz @dorothy-zbornak @mzhu25 |  | ||||||
|  | contracts/ @dekz @dextracker | ||||||
|   | |||||||
| @@ -38,7 +38,6 @@ These packages are all under development. See [/contracts/README.md](/contracts/ | |||||||
| | [`@0x/protocol-utils`](/packages/protocol-utils)         | [](https://www.npmjs.com/package/@0x/protocol-utils)         | A set of utilities for generating, parsing, signing and validating 0x orders                   | | | [`@0x/protocol-utils`](/packages/protocol-utils)         | [](https://www.npmjs.com/package/@0x/protocol-utils)         | A set of utilities for generating, parsing, signing and validating 0x orders                   | | ||||||
| | [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | A tiny utility library for getting known deployed contract addresses for a particular network. | | | [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | A tiny utility library for getting known deployed contract addresses for a particular network. | | ||||||
| | [`@0x/contract-wrappers`](/packages/contract-wrappers)   | [](https://www.npmjs.com/package/@0x/contract-wrappers)   | JS/TS wrappers for interacting with the 0x smart contracts                                     | | | [`@0x/contract-wrappers`](/packages/contract-wrappers)   | [](https://www.npmjs.com/package/@0x/contract-wrappers)   | JS/TS wrappers for interacting with the 0x smart contracts                                     | | ||||||
| | [`@0x/migrations`](/packages/migrations)                 | [](https://www.npmjs.com/package/@0x/migrations)                 | Migration tool for deploying 0x smart contracts on private testnets                            | |  | ||||||
| | [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts                                                        |  | | | [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts                                                        |  | | ||||||
|  |  | ||||||
| ## Usage | ## Usage | ||||||
|   | |||||||
| @@ -1,4 +1,85 @@ | |||||||
| [ | [ | ||||||
|  |     { | ||||||
|  |         "timestamp": 1659750766, | ||||||
|  |         "version": "3.3.34", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1658950329, | ||||||
|  |         "version": "3.3.33", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1655244958, | ||||||
|  |         "version": "3.3.32", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1654284040, | ||||||
|  |         "version": "3.3.31", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1652919697, | ||||||
|  |         "version": "3.3.30", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1650611093, | ||||||
|  |         "version": "3.3.29", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1648739346, | ||||||
|  |         "version": "3.3.28", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1646225739, | ||||||
|  |         "version": "3.3.27", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1645569128, | ||||||
|  |         "version": "3.3.26", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|         "timestamp": 1640364306, |         "timestamp": 1640364306, | ||||||
|         "version": "3.3.25", |         "version": "3.3.25", | ||||||
|   | |||||||
| @@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only. | |||||||
|  |  | ||||||
| CHANGELOG | CHANGELOG | ||||||
|  |  | ||||||
|  | ## v3.3.34 - _August 6, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.33 - _July 27, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.32 - _June 14, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.31 - _June 3, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.30 - _May 19, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.29 - _April 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.28 - _March 31, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.27 - _March 2, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v3.3.26 - _February 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
| ## v3.3.25 - _December 24, 2021_ | ## v3.3.25 - _December 24, 2021_ | ||||||
|  |  | ||||||
|     * Dependencies updated |     * Dependencies updated | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@0x/contracts-erc20", |     "name": "@0x/contracts-erc20", | ||||||
|     "version": "3.3.25", |     "version": "3.3.34", | ||||||
|     "engines": { |     "engines": { | ||||||
|         "node": ">=6.12" |         "node": ">=6.12" | ||||||
|     }, |     }, | ||||||
| @@ -51,18 +51,18 @@ | |||||||
|     }, |     }, | ||||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", |     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||||
|     "devDependencies": { |     "devDependencies": { | ||||||
|         "@0x/abi-gen": "^5.6.2", |         "@0x/abi-gen": "^5.8.0", | ||||||
|         "@0x/contracts-gen": "^2.0.40", |         "@0x/contracts-gen": "^2.0.46", | ||||||
|         "@0x/contracts-test-utils": "^5.4.16", |         "@0x/contracts-test-utils": "^5.4.25", | ||||||
|         "@0x/contracts-utils": "^4.8.6", |         "@0x/contracts-utils": "^4.8.15", | ||||||
|         "@0x/dev-utils": "^4.2.9", |         "@0x/dev-utils": "^4.2.14", | ||||||
|         "@0x/sol-compiler": "^4.7.5", |         "@0x/sol-compiler": "^4.8.1", | ||||||
|         "@0x/ts-doc-gen": "^0.0.28", |         "@0x/ts-doc-gen": "^0.0.28", | ||||||
|         "@0x/tslint-config": "^4.1.4", |         "@0x/tslint-config": "^4.1.4", | ||||||
|         "@0x/types": "^3.3.4", |         "@0x/types": "^3.3.6", | ||||||
|         "@0x/typescript-typings": "^5.2.1", |         "@0x/typescript-typings": "^5.3.1", | ||||||
|         "@0x/utils": "^6.4.4", |         "@0x/utils": "^6.5.3", | ||||||
|         "@0x/web3-wrapper": "^7.6.0", |         "@0x/web3-wrapper": "^7.6.5", | ||||||
|         "@types/lodash": "4.14.104", |         "@types/lodash": "4.14.104", | ||||||
|         "@types/mocha": "^5.2.7", |         "@types/mocha": "^5.2.7", | ||||||
|         "@types/node": "12.12.54", |         "@types/node": "12.12.54", | ||||||
| @@ -70,7 +70,7 @@ | |||||||
|         "chai-as-promised": "^7.1.0", |         "chai-as-promised": "^7.1.0", | ||||||
|         "chai-bignumber": "^3.0.0", |         "chai-bignumber": "^3.0.0", | ||||||
|         "dirty-chai": "^2.0.1", |         "dirty-chai": "^2.0.1", | ||||||
|         "ethereum-types": "^3.6.0", |         "ethereum-types": "^3.7.0", | ||||||
|         "lodash": "^4.17.11", |         "lodash": "^4.17.11", | ||||||
|         "make-promises-safe": "^1.1.0", |         "make-promises-safe": "^1.1.0", | ||||||
|         "mocha": "^6.2.0", |         "mocha": "^6.2.0", | ||||||
| @@ -79,10 +79,10 @@ | |||||||
|         "solhint": "^1.4.1", |         "solhint": "^1.4.1", | ||||||
|         "tslint": "5.11.0", |         "tslint": "5.11.0", | ||||||
|         "typedoc": "~0.16.11", |         "typedoc": "~0.16.11", | ||||||
|         "typescript": "4.2.2" |         "typescript": "4.6.3" | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "@0x/base-contract": "^6.4.2", |         "@0x/base-contract": "^6.5.0", | ||||||
|         "ethers": "~4.0.4" |         "ethers": "~4.0.4" | ||||||
|     }, |     }, | ||||||
|     "publishConfig": { |     "publishConfig": { | ||||||
|   | |||||||
| @@ -1,4 +1,85 @@ | |||||||
| [ | [ | ||||||
|  |     { | ||||||
|  |         "timestamp": 1659750766, | ||||||
|  |         "version": "5.4.25", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1658950329, | ||||||
|  |         "version": "5.4.24", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1655244958, | ||||||
|  |         "version": "5.4.23", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1654284040, | ||||||
|  |         "version": "5.4.22", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1652919697, | ||||||
|  |         "version": "5.4.21", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1650611093, | ||||||
|  |         "version": "5.4.20", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1648739346, | ||||||
|  |         "version": "5.4.19", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1646225739, | ||||||
|  |         "version": "5.4.18", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1645569128, | ||||||
|  |         "version": "5.4.17", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|         "timestamp": 1640364306, |         "timestamp": 1640364306, | ||||||
|         "version": "5.4.16", |         "version": "5.4.16", | ||||||
|   | |||||||
| @@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only. | |||||||
|  |  | ||||||
| CHANGELOG | CHANGELOG | ||||||
|  |  | ||||||
|  | ## v5.4.25 - _August 6, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.24 - _July 27, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.23 - _June 14, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.22 - _June 3, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.21 - _May 19, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.20 - _April 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.19 - _March 31, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.18 - _March 2, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v5.4.17 - _February 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
| ## v5.4.16 - _December 24, 2021_ | ## v5.4.16 - _December 24, 2021_ | ||||||
|  |  | ||||||
|     * Dependencies updated |     * Dependencies updated | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@0x/contracts-test-utils", |     "name": "@0x/contracts-test-utils", | ||||||
|     "version": "5.4.16", |     "version": "5.4.25", | ||||||
|     "engines": { |     "engines": { | ||||||
|         "node": ">=6.12" |         "node": ">=6.12" | ||||||
|     }, |     }, | ||||||
| @@ -34,28 +34,28 @@ | |||||||
|     }, |     }, | ||||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils", |     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils", | ||||||
|     "devDependencies": { |     "devDependencies": { | ||||||
|         "@0x/sol-compiler": "^4.7.5", |         "@0x/sol-compiler": "^4.8.1", | ||||||
|         "@0x/tslint-config": "^4.1.4", |         "@0x/tslint-config": "^4.1.4", | ||||||
|         "npm-run-all": "^4.1.2", |         "npm-run-all": "^4.1.2", | ||||||
|         "shx": "^0.2.2", |         "shx": "^0.2.2", | ||||||
|         "tslint": "5.11.0", |         "tslint": "5.11.0", | ||||||
|         "typescript": "4.2.2" |         "typescript": "4.6.3" | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "@0x/assert": "^3.0.29", |         "@0x/assert": "^3.0.34", | ||||||
|         "@0x/base-contract": "^6.4.2", |         "@0x/base-contract": "^6.5.0", | ||||||
|         "@0x/contract-addresses": "^6.11.0", |         "@0x/contract-addresses": "^6.19.0", | ||||||
|         "@0x/dev-utils": "^4.2.9", |         "@0x/dev-utils": "^4.2.14", | ||||||
|         "@0x/json-schemas": "^6.3.0", |         "@0x/json-schemas": "^6.4.4", | ||||||
|         "@0x/order-utils": "^10.4.28", |         "@0x/order-utils": "^10.4.28", | ||||||
|         "@0x/sol-coverage": "^4.0.39", |         "@0x/sol-coverage": "^4.0.45", | ||||||
|         "@0x/sol-profiler": "^4.1.29", |         "@0x/sol-profiler": "^4.1.35", | ||||||
|         "@0x/sol-trace": "^3.0.39", |         "@0x/sol-trace": "^3.0.45", | ||||||
|         "@0x/subproviders": "^6.6.0", |         "@0x/subproviders": "^6.6.5", | ||||||
|         "@0x/types": "^3.3.4", |         "@0x/types": "^3.3.6", | ||||||
|         "@0x/typescript-typings": "^5.2.1", |         "@0x/typescript-typings": "^5.3.1", | ||||||
|         "@0x/utils": "^6.4.4", |         "@0x/utils": "^6.5.3", | ||||||
|         "@0x/web3-wrapper": "^7.6.0", |         "@0x/web3-wrapper": "^7.6.5", | ||||||
|         "@types/bn.js": "^4.11.0", |         "@types/bn.js": "^4.11.0", | ||||||
|         "@types/js-combinatorics": "^0.5.29", |         "@types/js-combinatorics": "^0.5.29", | ||||||
|         "@types/lodash": "4.14.104", |         "@types/lodash": "4.14.104", | ||||||
| @@ -67,7 +67,7 @@ | |||||||
|         "chai-bignumber": "^3.0.0", |         "chai-bignumber": "^3.0.0", | ||||||
|         "decimal.js": "^10.2.0", |         "decimal.js": "^10.2.0", | ||||||
|         "dirty-chai": "^2.0.1", |         "dirty-chai": "^2.0.1", | ||||||
|         "ethereum-types": "^3.6.0", |         "ethereum-types": "^3.7.0", | ||||||
|         "ethereumjs-util": "^7.0.10", |         "ethereumjs-util": "^7.0.10", | ||||||
|         "ethers": "~4.0.4", |         "ethers": "~4.0.4", | ||||||
|         "js-combinatorics": "^0.5.3", |         "js-combinatorics": "^0.5.3", | ||||||
|   | |||||||
| @@ -1,4 +1,85 @@ | |||||||
| [ | [ | ||||||
|  |     { | ||||||
|  |         "timestamp": 1659750766, | ||||||
|  |         "version": "1.4.17", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1658950329, | ||||||
|  |         "version": "1.4.16", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1655244958, | ||||||
|  |         "version": "1.4.15", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1654284040, | ||||||
|  |         "version": "1.4.14", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1652919697, | ||||||
|  |         "version": "1.4.13", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1650611093, | ||||||
|  |         "version": "1.4.12", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1648739346, | ||||||
|  |         "version": "1.4.11", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1646225739, | ||||||
|  |         "version": "1.4.10", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1645569128, | ||||||
|  |         "version": "1.4.9", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|         "timestamp": 1640364306, |         "timestamp": 1640364306, | ||||||
|         "version": "1.4.8", |         "version": "1.4.8", | ||||||
|   | |||||||
| @@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only. | |||||||
|  |  | ||||||
| CHANGELOG | CHANGELOG | ||||||
|  |  | ||||||
|  | ## v1.4.17 - _August 6, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.16 - _July 27, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.15 - _June 14, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.14 - _June 3, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.13 - _May 19, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.12 - _April 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.11 - _March 31, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.10 - _March 2, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v1.4.9 - _February 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
| ## v1.4.8 - _December 24, 2021_ | ## v1.4.8 - _December 24, 2021_ | ||||||
|  |  | ||||||
|     * Dependencies updated |     * Dependencies updated | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@0x/contracts-treasury", |     "name": "@0x/contracts-treasury", | ||||||
|     "version": "1.4.8", |     "version": "1.4.17", | ||||||
|     "engines": { |     "engines": { | ||||||
|         "node": ">=6.12" |         "node": ">=6.12" | ||||||
|     }, |     }, | ||||||
| @@ -46,14 +46,14 @@ | |||||||
|     }, |     }, | ||||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury", |     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury", | ||||||
|     "devDependencies": { |     "devDependencies": { | ||||||
|         "@0x/abi-gen": "^5.6.2", |         "@0x/abi-gen": "^5.8.0", | ||||||
|         "@0x/contract-addresses": "^6.11.0", |         "@0x/contract-addresses": "^6.19.0", | ||||||
|         "@0x/contracts-asset-proxy": "^3.7.19", |         "@0x/contracts-asset-proxy": "^3.7.19", | ||||||
|         "@0x/contracts-erc20": "^3.3.25", |         "@0x/contracts-erc20": "^3.3.34", | ||||||
|         "@0x/contracts-gen": "^2.0.40", |         "@0x/contracts-gen": "^2.0.46", | ||||||
|         "@0x/contracts-staking": "^2.0.45", |         "@0x/contracts-staking": "^2.0.45", | ||||||
|         "@0x/contracts-test-utils": "^5.4.16", |         "@0x/contracts-test-utils": "^5.4.25", | ||||||
|         "@0x/sol-compiler": "^4.7.5", |         "@0x/sol-compiler": "^4.8.1", | ||||||
|         "@0x/ts-doc-gen": "^0.0.28", |         "@0x/ts-doc-gen": "^0.0.28", | ||||||
|         "@0x/tslint-config": "^4.1.4", |         "@0x/tslint-config": "^4.1.4", | ||||||
|         "@types/isomorphic-fetch": "^0.0.35", |         "@types/isomorphic-fetch": "^0.0.35", | ||||||
| @@ -69,17 +69,17 @@ | |||||||
|         "solhint": "^1.4.1", |         "solhint": "^1.4.1", | ||||||
|         "tslint": "5.11.0", |         "tslint": "5.11.0", | ||||||
|         "typedoc": "~0.16.11", |         "typedoc": "~0.16.11", | ||||||
|         "typescript": "4.2.2" |         "typescript": "4.6.3" | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "@0x/base-contract": "^6.4.2", |         "@0x/base-contract": "^6.5.0", | ||||||
|         "@0x/protocol-utils": "^1.10.1", |         "@0x/protocol-utils": "^11.16.1", | ||||||
|         "@0x/subproviders": "^6.6.0", |         "@0x/subproviders": "^6.6.5", | ||||||
|         "@0x/types": "^3.3.4", |         "@0x/types": "^3.3.6", | ||||||
|         "@0x/typescript-typings": "^5.2.1", |         "@0x/typescript-typings": "^5.3.1", | ||||||
|         "@0x/utils": "^6.4.4", |         "@0x/utils": "^6.5.3", | ||||||
|         "@0x/web3-wrapper": "^7.6.0", |         "@0x/web3-wrapper": "^7.6.5", | ||||||
|         "ethereum-types": "^3.6.0", |         "ethereum-types": "^3.7.0", | ||||||
|         "ethereumjs-util": "^7.0.10" |         "ethereumjs-util": "^7.0.10" | ||||||
|     }, |     }, | ||||||
|     "publishConfig": { |     "publishConfig": { | ||||||
|   | |||||||
| @@ -1,4 +1,85 @@ | |||||||
| [ | [ | ||||||
|  |     { | ||||||
|  |         "timestamp": 1659750766, | ||||||
|  |         "version": "4.8.15", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1658950329, | ||||||
|  |         "version": "4.8.14", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1655244958, | ||||||
|  |         "version": "4.8.13", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1654284040, | ||||||
|  |         "version": "4.8.12", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1652919697, | ||||||
|  |         "version": "4.8.11", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1650611093, | ||||||
|  |         "version": "4.8.10", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1648739346, | ||||||
|  |         "version": "4.8.9", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1646225739, | ||||||
|  |         "version": "4.8.8", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1645569128, | ||||||
|  |         "version": "4.8.7", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|         "timestamp": 1640364306, |         "timestamp": 1640364306, | ||||||
|         "version": "4.8.6", |         "version": "4.8.6", | ||||||
|   | |||||||
| @@ -5,6 +5,42 @@ Edit the package's CHANGELOG.json file only. | |||||||
|  |  | ||||||
| CHANGELOG | CHANGELOG | ||||||
|  |  | ||||||
|  | ## v4.8.15 - _August 6, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.14 - _July 27, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.13 - _June 14, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.12 - _June 3, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.11 - _May 19, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.10 - _April 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.9 - _March 31, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.8 - _March 2, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v4.8.7 - _February 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
| ## v4.8.6 - _December 24, 2021_ | ## v4.8.6 - _December 24, 2021_ | ||||||
|  |  | ||||||
|     * Dependencies updated |     * Dependencies updated | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@0x/contracts-utils", |     "name": "@0x/contracts-utils", | ||||||
|     "version": "4.8.6", |     "version": "4.8.15", | ||||||
|     "engines": { |     "engines": { | ||||||
|         "node": ">=6.12" |         "node": ">=6.12" | ||||||
|     }, |     }, | ||||||
| @@ -50,15 +50,15 @@ | |||||||
|     }, |     }, | ||||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils", |     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils", | ||||||
|     "devDependencies": { |     "devDependencies": { | ||||||
|         "@0x/abi-gen": "^5.6.2", |         "@0x/abi-gen": "^5.8.0", | ||||||
|         "@0x/contracts-gen": "^2.0.40", |         "@0x/contracts-gen": "^2.0.46", | ||||||
|         "@0x/contracts-test-utils": "^5.4.16", |         "@0x/contracts-test-utils": "^5.4.25", | ||||||
|         "@0x/dev-utils": "^4.2.9", |         "@0x/dev-utils": "^4.2.14", | ||||||
|         "@0x/order-utils": "^10.4.28", |         "@0x/order-utils": "^10.4.28", | ||||||
|         "@0x/sol-compiler": "^4.7.5", |         "@0x/sol-compiler": "^4.8.1", | ||||||
|         "@0x/tslint-config": "^4.1.4", |         "@0x/tslint-config": "^4.1.4", | ||||||
|         "@0x/types": "^3.3.4", |         "@0x/types": "^3.3.6", | ||||||
|         "@0x/web3-wrapper": "^7.6.0", |         "@0x/web3-wrapper": "^7.6.5", | ||||||
|         "@types/bn.js": "^4.11.0", |         "@types/bn.js": "^4.11.0", | ||||||
|         "@types/lodash": "4.14.104", |         "@types/lodash": "4.14.104", | ||||||
|         "@types/mocha": "^5.2.7", |         "@types/mocha": "^5.2.7", | ||||||
| @@ -76,14 +76,14 @@ | |||||||
|         "solhint": "^1.4.1", |         "solhint": "^1.4.1", | ||||||
|         "truffle": "^5.0.32", |         "truffle": "^5.0.32", | ||||||
|         "tslint": "5.11.0", |         "tslint": "5.11.0", | ||||||
|         "typescript": "4.2.2" |         "typescript": "4.6.3" | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "@0x/base-contract": "^6.4.2", |         "@0x/base-contract": "^6.5.0", | ||||||
|         "@0x/typescript-typings": "^5.2.1", |         "@0x/typescript-typings": "^5.3.1", | ||||||
|         "@0x/utils": "^6.4.4", |         "@0x/utils": "^6.5.3", | ||||||
|         "bn.js": "^4.11.8", |         "bn.js": "^4.11.8", | ||||||
|         "ethereum-types": "^3.6.0" |         "ethereum-types": "^3.7.0" | ||||||
|     }, |     }, | ||||||
|     "publishConfig": { |     "publishConfig": { | ||||||
|         "access": "public" |         "access": "public" | ||||||
|   | |||||||
| @@ -1,4 +1,99 @@ | |||||||
| [ | [ | ||||||
|  |     { | ||||||
|  |         "timestamp": 1659750766, | ||||||
|  |         "version": "0.36.1", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "version": "0.36.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Add Synthetix support in Ethereum and Optimism bridge adapters", | ||||||
|  |                 "pr": 518 | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "timestamp": 1658950329 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "version": "0.35.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Adds support for Velodrome OptimismBridgeAdapter", | ||||||
|  |                 "pr": 494 | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "timestamp": 1655244958 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "version": "0.34.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Splits BridgeAdapter up by chain", | ||||||
|  |                 "pr": 487 | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "note": "Add stETH wrap/unwrap support", | ||||||
|  |                 "pr": 476 | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 "note": "Adds support for BancorV3 to EthereumBridgeAdapter", | ||||||
|  |                 "pr": 492 | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "timestamp": 1654284040 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "version": "0.33.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Add support for GMX and Platypus to bridge adapter", | ||||||
|  |                 "pr": 478 | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "timestamp": 1652919697 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "version": "0.32.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Add support for `BalancerV2Batch` fills in FQT", | ||||||
|  |                 "pr": 462 | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "timestamp": 1650611093 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1648739346, | ||||||
|  |         "version": "0.31.2", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "timestamp": 1646225739, | ||||||
|  |         "version": "0.31.1", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Dependencies updated" | ||||||
|  |             } | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "version": "0.31.0", | ||||||
|  |         "changes": [ | ||||||
|  |             { | ||||||
|  |                 "note": "Add ERC721OrdersFeature, ERC1155OrdersFeature, and ERC165Feature", | ||||||
|  |                 "pr": 429 | ||||||
|  |             } | ||||||
|  |         ], | ||||||
|  |         "timestamp": 1645569128 | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|         "timestamp": 1640364306, |         "timestamp": 1640364306, | ||||||
|         "version": "0.30.1", |         "version": "0.30.1", | ||||||
|   | |||||||
| @@ -5,6 +5,44 @@ Edit the package's CHANGELOG.json file only. | |||||||
|  |  | ||||||
| CHANGELOG | CHANGELOG | ||||||
|  |  | ||||||
|  | ## v0.36.1 - _August 6, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v0.36.0 - _July 27, 2022_ | ||||||
|  |  | ||||||
|  |     * Add Synthetix support in Ethereum and Optimism bridge adapters (#518) | ||||||
|  |  | ||||||
|  | ## v0.35.0 - _June 14, 2022_ | ||||||
|  |  | ||||||
|  |     * Adds support for Velodrome OptimismBridgeAdapter (#494) | ||||||
|  |  | ||||||
|  | ## v0.34.0 - _June 3, 2022_ | ||||||
|  |  | ||||||
|  |     * Splits BridgeAdapter up by chain (#487) | ||||||
|  |     * Add stETH wrap/unwrap support (#476) | ||||||
|  |     * Adds support for BancorV3 to EthereumBridgeAdapter (#492) | ||||||
|  |  | ||||||
|  | ## v0.33.0 - _May 19, 2022_ | ||||||
|  |  | ||||||
|  |     * Add support for GMX and Platypus to bridge adapter (#478) | ||||||
|  |  | ||||||
|  | ## v0.32.0 - _April 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Add support for `BalancerV2Batch` fills in FQT (#462) | ||||||
|  |  | ||||||
|  | ## v0.31.2 - _March 31, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v0.31.1 - _March 2, 2022_ | ||||||
|  |  | ||||||
|  |     * Dependencies updated | ||||||
|  |  | ||||||
|  | ## v0.31.0 - _February 22, 2022_ | ||||||
|  |  | ||||||
|  |     * Add ERC721OrdersFeature, ERC1155OrdersFeature, and ERC165Feature (#429) | ||||||
|  |  | ||||||
| ## v0.30.1 - _December 24, 2021_ | ## v0.30.1 - _December 24, 2021_ | ||||||
|  |  | ||||||
|     * Dependencies updated |     * Dependencies updated | ||||||
|   | |||||||
| @@ -34,6 +34,9 @@ import "./features/interfaces/IBatchFillNativeOrdersFeature.sol"; | |||||||
| import "./features/interfaces/IMultiplexFeature.sol"; | import "./features/interfaces/IMultiplexFeature.sol"; | ||||||
| import "./features/interfaces/IOtcOrdersFeature.sol"; | import "./features/interfaces/IOtcOrdersFeature.sol"; | ||||||
| import "./features/interfaces/IFundRecoveryFeature.sol"; | import "./features/interfaces/IFundRecoveryFeature.sol"; | ||||||
|  | import "./features/interfaces/IERC721OrdersFeature.sol"; | ||||||
|  | import "./features/interfaces/IERC1155OrdersFeature.sol"; | ||||||
|  | import "./features/interfaces/IERC165Feature.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
| /// @dev Interface for a fully featured Exchange Proxy. | /// @dev Interface for a fully featured Exchange Proxy. | ||||||
| @@ -50,7 +53,10 @@ interface IZeroEx is | |||||||
|     IBatchFillNativeOrdersFeature, |     IBatchFillNativeOrdersFeature, | ||||||
|     IMultiplexFeature, |     IMultiplexFeature, | ||||||
|     IOtcOrdersFeature, |     IOtcOrdersFeature, | ||||||
|     IFundRecoveryFeature |     IFundRecoveryFeature, | ||||||
|  |     IERC721OrdersFeature, | ||||||
|  |     IERC1155OrdersFeature, | ||||||
|  |     IERC165Feature | ||||||
| { | { | ||||||
|     // solhint-disable state-visibility |     // solhint-disable state-visibility | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,229 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | library LibNFTOrdersRichErrors { | ||||||
|  |  | ||||||
|  |     // solhint-disable func-name-mixedcase | ||||||
|  |  | ||||||
|  |     function OverspentEthError( | ||||||
|  |         uint256 ethSpent, | ||||||
|  |         uint256 ethAvailable | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("OverspentEthError(uint256,uint256)")), | ||||||
|  |             ethSpent, | ||||||
|  |             ethAvailable | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function InsufficientEthError( | ||||||
|  |         uint256 ethAvailable, | ||||||
|  |         uint256 orderAmount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("InsufficientEthError(uint256,uint256)")), | ||||||
|  |             ethAvailable, | ||||||
|  |             orderAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function ERC721TokenMismatchError( | ||||||
|  |         address token1, | ||||||
|  |         address token2 | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("ERC721TokenMismatchError(address,address)")), | ||||||
|  |             token1, | ||||||
|  |             token2 | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function ERC1155TokenMismatchError( | ||||||
|  |         address token1, | ||||||
|  |         address token2 | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("ERC1155TokenMismatchError(address,address)")), | ||||||
|  |             token1, | ||||||
|  |             token2 | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function ERC20TokenMismatchError( | ||||||
|  |         address token1, | ||||||
|  |         address token2 | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("ERC20TokenMismatchError(address,address)")), | ||||||
|  |             token1, | ||||||
|  |             token2 | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function NegativeSpreadError( | ||||||
|  |         uint256 sellOrderAmount, | ||||||
|  |         uint256 buyOrderAmount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("NegativeSpreadError(uint256,uint256)")), | ||||||
|  |             sellOrderAmount, | ||||||
|  |             buyOrderAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function SellOrderFeesExceedSpreadError( | ||||||
|  |         uint256 sellOrderFees, | ||||||
|  |         uint256 spread | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("SellOrderFeesExceedSpreadError(uint256,uint256)")), | ||||||
|  |             sellOrderFees, | ||||||
|  |             spread | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function OnlyTakerError( | ||||||
|  |         address sender, | ||||||
|  |         address taker | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("OnlyTakerError(address,address)")), | ||||||
|  |             sender, | ||||||
|  |             taker | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function InvalidSignerError( | ||||||
|  |         address maker, | ||||||
|  |         address signer | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("InvalidSignerError(address,address)")), | ||||||
|  |             maker, | ||||||
|  |             signer | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function OrderNotFillableError( | ||||||
|  |         address maker, | ||||||
|  |         uint256 nonce, | ||||||
|  |         uint8 orderStatus | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("OrderNotFillableError(address,uint256,uint8)")), | ||||||
|  |             maker, | ||||||
|  |             nonce, | ||||||
|  |             orderStatus | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function TokenIdMismatchError( | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 orderTokenId | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("TokenIdMismatchError(uint256,uint256)")), | ||||||
|  |             tokenId, | ||||||
|  |             orderTokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function PropertyValidationFailedError( | ||||||
|  |         address propertyValidator, | ||||||
|  |         address token, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         bytes memory propertyData, | ||||||
|  |         bytes memory errorData | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("PropertyValidationFailedError(address,address,uint256,bytes,bytes)")), | ||||||
|  |             propertyValidator, | ||||||
|  |             token, | ||||||
|  |             tokenId, | ||||||
|  |             propertyData, | ||||||
|  |             errorData | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function ExceedsRemainingOrderAmount( | ||||||
|  |         uint128 remainingOrderAmount, | ||||||
|  |         uint128 fillAmount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes memory) | ||||||
|  |     { | ||||||
|  |         return abi.encodeWithSelector( | ||||||
|  |             bytes4(keccak256("ExceedsRemainingOrderAmount(uint128,uint128)")), | ||||||
|  |             remainingOrderAmount, | ||||||
|  |             fillAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								contracts/zero-ex/contracts/src/features/ERC165Feature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								contracts/zero-ex/contracts/src/features/ERC165Feature.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "../fixins/FixinCommon.sol"; | ||||||
|  | import "./interfaces/IFeature.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Implements the ERC165 `supportsInterface` function | ||||||
|  | contract ERC165Feature is | ||||||
|  |     IFeature, | ||||||
|  |     FixinCommon | ||||||
|  | { | ||||||
|  |     /// @dev Name of this feature. | ||||||
|  |     string public constant override FEATURE_NAME = "ERC165"; | ||||||
|  |     /// @dev Version of this feature. | ||||||
|  |     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0); | ||||||
|  |  | ||||||
|  |     /// @dev Indicates whether the 0x Exchange Proxy implements a particular | ||||||
|  |     ///      ERC165 interface. This function should use at most 30,000 gas. | ||||||
|  |     /// @param interfaceId The interface identifier, as specified in ERC165. | ||||||
|  |     /// @return isSupported Whether the given interface is supported by the | ||||||
|  |     ///         0x Exchange Proxy. | ||||||
|  |     function supportInterface(bytes4 interfaceId) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (bool isSupported) | ||||||
|  |     { | ||||||
|  |         return interfaceId == 0x01ffc9a7 || // ERC-165 support | ||||||
|  |                interfaceId == 0x150b7a02 || // ERC-721 `ERC721TokenReceiver` support | ||||||
|  |                interfaceId == 0x4e2312e0;   // ERC-1155 `ERC1155TokenReceiver` support | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -311,7 +311,7 @@ contract OtcOrdersFeature is | |||||||
|         // Unwrap WETH |         // Unwrap WETH | ||||||
|         WETH.withdraw(order.makerAmount); |         WETH.withdraw(order.makerAmount); | ||||||
|         // Transfer ETH to taker |         // Transfer ETH to taker | ||||||
|         _transferEth(taker, order.makerAmount); |         _transferEth(payable(taker), order.makerAmount); | ||||||
|  |  | ||||||
|         emit OtcOrderFilled( |         emit OtcOrderFilled( | ||||||
|             orderInfo.orderHash, |             orderInfo.orderHash, | ||||||
| @@ -622,16 +622,4 @@ contract OtcOrdersFeature is | |||||||
|             [txOrigin] |             [txOrigin] | ||||||
|             [nonceBucket]; |             [nonceBucket]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function _transferEth(address recipient, uint256 amount) |  | ||||||
|         private |  | ||||||
|     { |  | ||||||
|         // Transfer ETH to recipient |  | ||||||
|         (bool success, bytes memory revertData) = |  | ||||||
|             recipient.call{value: amount}(""); |  | ||||||
|         // Revert on failure |  | ||||||
|         if (!success) { |  | ||||||
|             revertData.rrevert(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,242 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "../libs/LibNFTOrder.sol"; | ||||||
|  | import "../libs/LibSignature.sol"; | ||||||
|  | import "../../vendor/IERC1155Token.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Feature for interacting with ERC1155 orders. | ||||||
|  | interface IERC1155OrdersFeature { | ||||||
|  |  | ||||||
|  |     /// @dev Emitted whenever an `ERC1155Order` is filled. | ||||||
|  |     /// @param direction Whether the order is selling or | ||||||
|  |     ///        buying the ERC1155 token. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     /// @param taker The taker of the order. | ||||||
|  |     /// @param nonce The unique maker nonce in the order. | ||||||
|  |     /// @param erc20Token The address of the ERC20 token. | ||||||
|  |     /// @param erc20FillAmount The amount of ERC20 token filled. | ||||||
|  |     /// @param erc1155Token The address of the ERC1155 token. | ||||||
|  |     /// @param erc1155TokenId The ID of the ERC1155 asset. | ||||||
|  |     /// @param erc1155FillAmount The amount of ERC1155 asset filled. | ||||||
|  |     /// @param matcher Currently unused. | ||||||
|  |     event ERC1155OrderFilled( | ||||||
|  |         LibNFTOrder.TradeDirection direction, | ||||||
|  |         address maker, | ||||||
|  |         address taker, | ||||||
|  |         uint256 nonce, | ||||||
|  |         IERC20TokenV06 erc20Token, | ||||||
|  |         uint256 erc20FillAmount, | ||||||
|  |         IERC1155Token erc1155Token, | ||||||
|  |         uint256 erc1155TokenId, | ||||||
|  |         uint128 erc1155FillAmount, | ||||||
|  |         address matcher | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Emitted whenever an `ERC1155Order` is cancelled. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     /// @param nonce The nonce of the order that was cancelled. | ||||||
|  |     event ERC1155OrderCancelled( | ||||||
|  |         address maker, | ||||||
|  |         uint256 nonce | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Emitted when an `ERC1155Order` is pre-signed. | ||||||
|  |     ///      Contains all the fields of the order. | ||||||
|  |     event ERC1155OrderPreSigned( | ||||||
|  |         LibNFTOrder.TradeDirection direction, | ||||||
|  |         address maker, | ||||||
|  |         address taker, | ||||||
|  |         uint256 expiry, | ||||||
|  |         uint256 nonce, | ||||||
|  |         IERC20TokenV06 erc20Token, | ||||||
|  |         uint256 erc20TokenAmount, | ||||||
|  |         LibNFTOrder.Fee[] fees, | ||||||
|  |         IERC1155Token erc1155Token, | ||||||
|  |         uint256 erc1155TokenId, | ||||||
|  |         LibNFTOrder.Property[] erc1155TokenProperties, | ||||||
|  |         uint128 erc1155TokenAmount | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Sells an ERC1155 asset to fill the given order. | ||||||
|  |     /// @param buyOrder The ERC1155 buy order. | ||||||
|  |     /// @param signature The order signature from the maker. | ||||||
|  |     /// @param erc1155TokenId The ID of the ERC1155 asset being | ||||||
|  |     ///        sold. If the given order specifies properties, | ||||||
|  |     ///        the asset must satisfy those properties. Otherwise, | ||||||
|  |     ///        it must equal the tokenId in the order. | ||||||
|  |     /// @param erc1155SellAmount The amount of the ERC1155 asset | ||||||
|  |     ///        to sell. | ||||||
|  |     /// @param unwrapNativeToken If this parameter is true and the | ||||||
|  |     ///        ERC20 token of the order is e.g. WETH, unwraps the | ||||||
|  |     ///        token before transferring it to the taker. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC1155OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC20 tokens have been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC1155 asset to the buyer. | ||||||
|  |     function sellERC1155( | ||||||
|  |         LibNFTOrder.ERC1155Order calldata buyOrder, | ||||||
|  |         LibSignature.Signature calldata signature, | ||||||
|  |         uint256 erc1155TokenId, | ||||||
|  |         uint128 erc1155SellAmount, | ||||||
|  |         bool unwrapNativeToken, | ||||||
|  |         bytes calldata callbackData | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Buys an ERC1155 asset by filling the given order. | ||||||
|  |     /// @param sellOrder The ERC1155 sell order. | ||||||
|  |     /// @param signature The order signature. | ||||||
|  |     /// @param erc1155BuyAmount The amount of the ERC1155 asset | ||||||
|  |     ///        to buy. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC1155OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC1155 asset has been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC20 tokens to the seller. | ||||||
|  |     ///        Native tokens acquired during the callback can be used | ||||||
|  |     ///        to fill the order. | ||||||
|  |     function buyERC1155( | ||||||
|  |         LibNFTOrder.ERC1155Order calldata sellOrder, | ||||||
|  |         LibSignature.Signature calldata signature, | ||||||
|  |         uint128 erc1155BuyAmount, | ||||||
|  |         bytes calldata callbackData | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         payable; | ||||||
|  |  | ||||||
|  |     /// @dev Cancel a single ERC1155 order by its nonce. The caller | ||||||
|  |     ///      should be the maker of the order. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonce The order nonce. | ||||||
|  |     function cancelERC1155Order(uint256 orderNonce) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Cancel multiple ERC1155 orders by their nonces. The caller | ||||||
|  |     ///      should be the maker of the orders. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonces The order nonces. | ||||||
|  |     function batchCancelERC1155Orders(uint256[] calldata orderNonces) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Buys multiple ERC1155 assets by filling the | ||||||
|  |     ///      given orders. | ||||||
|  |     /// @param sellOrders The ERC1155 sell orders. | ||||||
|  |     /// @param signatures The order signatures. | ||||||
|  |     /// @param erc1155TokenAmounts The amounts of the ERC1155 assets | ||||||
|  |     ///        to buy for each order. | ||||||
|  |     /// @param callbackData The data (if any) to pass to the taker | ||||||
|  |     ///        callback for each order. Refer to the `callbackData` | ||||||
|  |     ///        parameter to for `buyERC1155`. | ||||||
|  |     /// @param revertIfIncomplete If true, reverts if this | ||||||
|  |     ///        function fails to fill any individual order. | ||||||
|  |     /// @return successes An array of booleans corresponding to whether | ||||||
|  |     ///         each order in `orders` was successfully filled. | ||||||
|  |     function batchBuyERC1155s( | ||||||
|  |         LibNFTOrder.ERC1155Order[] calldata sellOrders, | ||||||
|  |         LibSignature.Signature[] calldata signatures, | ||||||
|  |         uint128[] calldata erc1155TokenAmounts, | ||||||
|  |         bytes[] calldata callbackData, | ||||||
|  |         bool revertIfIncomplete | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         payable | ||||||
|  |         returns (bool[] memory successes); | ||||||
|  |  | ||||||
|  |     /// @dev Callback for the ERC1155 `safeTransferFrom` function. | ||||||
|  |     ///      This callback can be used to sell an ERC1155 asset if | ||||||
|  |     ///      a valid ERC1155 order, signature and `unwrapNativeToken` | ||||||
|  |     ///      are encoded in `data`. This allows takers to sell their | ||||||
|  |     ///      ERC1155 asset without first calling `setApprovalForAll`. | ||||||
|  |     /// @param operator The address which called `safeTransferFrom`. | ||||||
|  |     /// @param from The address which previously owned the token. | ||||||
|  |     /// @param tokenId The ID of the asset being transferred. | ||||||
|  |     /// @param value The amount being transferred. | ||||||
|  |     /// @param data Additional data with no specified format. If a | ||||||
|  |     ///        valid ERC1155 order, signature and `unwrapNativeToken` | ||||||
|  |     ///        are encoded in `data`, this function will try to fill | ||||||
|  |     ///        the order using the received asset. | ||||||
|  |     /// @return success The selector of this function (0xf23a6e61), | ||||||
|  |     ///         indicating that the callback succeeded. | ||||||
|  |     function onERC1155Received( | ||||||
|  |         address operator, | ||||||
|  |         address from, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 value, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success); | ||||||
|  |  | ||||||
|  |     /// @dev Approves an ERC1155 order on-chain. After pre-signing | ||||||
|  |     ///      the order, the `PRESIGNED` signature type will become | ||||||
|  |     ///      valid for that order and signer. | ||||||
|  |     /// @param order An ERC1155 order. | ||||||
|  |     function preSignERC1155Order(LibNFTOrder.ERC1155Order calldata order) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Checks whether the given signature is valid for the | ||||||
|  |     ///      the given ERC1155 order. Reverts if not. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @param signature The signature to validate. | ||||||
|  |     function validateERC1155OrderSignature( | ||||||
|  |         LibNFTOrder.ERC1155Order calldata order, | ||||||
|  |         LibSignature.Signature calldata signature | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         view; | ||||||
|  |  | ||||||
|  |     /// @dev If the given order is buying an ERC1155 asset, checks | ||||||
|  |     ///      whether or not the given token ID satisfies the required | ||||||
|  |     ///      properties specified in the order. If the order does not | ||||||
|  |     ///      specify any properties, this function instead checks | ||||||
|  |     ///      whether the given token ID matches the ID in the order. | ||||||
|  |     ///      Reverts if any checks fail, or if the order is selling | ||||||
|  |     ///      an ERC1155 asset. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @param erc1155TokenId The ID of the ERC1155 asset. | ||||||
|  |     function validateERC1155OrderProperties( | ||||||
|  |         LibNFTOrder.ERC1155Order calldata order, | ||||||
|  |         uint256 erc1155TokenId | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         view; | ||||||
|  |  | ||||||
|  |     /// @dev Get the order info for an ERC1155 order. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @return orderInfo Infor about the order. | ||||||
|  |     function getERC1155OrderInfo(LibNFTOrder.ERC1155Order calldata order) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderInfo memory orderInfo); | ||||||
|  |  | ||||||
|  |     /// @dev Get the EIP-712 hash of an ERC1155 order. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @return orderHash The order hash. | ||||||
|  |     function getERC1155OrderHash(LibNFTOrder.ERC1155Order calldata order) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (bytes32 orderHash); | ||||||
|  | } | ||||||
| @@ -0,0 +1,36 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Implements the ERC165 `supportsInterface` function | ||||||
|  | interface IERC165Feature { | ||||||
|  |  | ||||||
|  |     /// @dev Indicates whether the 0x Exchange Proxy implements a particular | ||||||
|  |     ///      ERC165 interface. This function should use at most 30,000 gas. | ||||||
|  |     /// @param interfaceId The interface identifier, as specified in ERC165. | ||||||
|  |     /// @return isSupported Whether the given interface is supported by the | ||||||
|  |     ///         0x Exchange Proxy. | ||||||
|  |     function supportInterface(bytes4 interfaceId) | ||||||
|  |         external | ||||||
|  |         pure | ||||||
|  |         returns (bool isSupported); | ||||||
|  | } | ||||||
| @@ -0,0 +1,286 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "../libs/LibNFTOrder.sol"; | ||||||
|  | import "../libs/LibSignature.sol"; | ||||||
|  | import "../../vendor/IERC721Token.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Feature for interacting with ERC721 orders. | ||||||
|  | interface IERC721OrdersFeature { | ||||||
|  |  | ||||||
|  |     /// @dev Emitted whenever an `ERC721Order` is filled. | ||||||
|  |     /// @param direction Whether the order is selling or | ||||||
|  |     ///        buying the ERC721 token. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     /// @param taker The taker of the order. | ||||||
|  |     /// @param nonce The unique maker nonce in the order. | ||||||
|  |     /// @param erc20Token The address of the ERC20 token. | ||||||
|  |     /// @param erc20TokenAmount The amount of ERC20 token | ||||||
|  |     ///        to sell or buy. | ||||||
|  |     /// @param erc721Token The address of the ERC721 token. | ||||||
|  |     /// @param erc721TokenId The ID of the ERC721 asset. | ||||||
|  |     /// @param matcher If this order was matched with another using `matchERC721Orders()`, | ||||||
|  |     ///                this will be the address of the caller. If not, this will be `address(0)`. | ||||||
|  |     event ERC721OrderFilled( | ||||||
|  |         LibNFTOrder.TradeDirection direction, | ||||||
|  |         address maker, | ||||||
|  |         address taker, | ||||||
|  |         uint256 nonce, | ||||||
|  |         IERC20TokenV06 erc20Token, | ||||||
|  |         uint256 erc20TokenAmount, | ||||||
|  |         IERC721Token erc721Token, | ||||||
|  |         uint256 erc721TokenId, | ||||||
|  |         address matcher | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Emitted whenever an `ERC721Order` is cancelled. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     /// @param nonce The nonce of the order that was cancelled. | ||||||
|  |     event ERC721OrderCancelled( | ||||||
|  |         address maker, | ||||||
|  |         uint256 nonce | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Emitted when an `ERC721Order` is pre-signed. | ||||||
|  |     ///      Contains all the fields of the order. | ||||||
|  |     event ERC721OrderPreSigned( | ||||||
|  |         LibNFTOrder.TradeDirection direction, | ||||||
|  |         address maker, | ||||||
|  |         address taker, | ||||||
|  |         uint256 expiry, | ||||||
|  |         uint256 nonce, | ||||||
|  |         IERC20TokenV06 erc20Token, | ||||||
|  |         uint256 erc20TokenAmount, | ||||||
|  |         LibNFTOrder.Fee[] fees, | ||||||
|  |         IERC721Token erc721Token, | ||||||
|  |         uint256 erc721TokenId, | ||||||
|  |         LibNFTOrder.Property[] erc721TokenProperties | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Sells an ERC721 asset to fill the given order. | ||||||
|  |     /// @param buyOrder The ERC721 buy order. | ||||||
|  |     /// @param signature The order signature from the maker. | ||||||
|  |     /// @param erc721TokenId The ID of the ERC721 asset being | ||||||
|  |     ///        sold. If the given order specifies properties, | ||||||
|  |     ///        the asset must satisfy those properties. Otherwise, | ||||||
|  |     ///        it must equal the tokenId in the order. | ||||||
|  |     /// @param unwrapNativeToken If this parameter is true and the | ||||||
|  |     ///        ERC20 token of the order is e.g. WETH, unwraps the | ||||||
|  |     ///        token before transferring it to the taker. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC721OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC20 tokens have been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC721 asset to the buyer. | ||||||
|  |     function sellERC721( | ||||||
|  |         LibNFTOrder.ERC721Order calldata buyOrder, | ||||||
|  |         LibSignature.Signature calldata signature, | ||||||
|  |         uint256 erc721TokenId, | ||||||
|  |         bool unwrapNativeToken, | ||||||
|  |         bytes calldata callbackData | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Buys an ERC721 asset by filling the given order. | ||||||
|  |     /// @param sellOrder The ERC721 sell order. | ||||||
|  |     /// @param signature The order signature. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC721OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC721 asset has been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC20 tokens to the seller. | ||||||
|  |     ///        Native tokens acquired during the callback can be used | ||||||
|  |     ///        to fill the order. | ||||||
|  |     function buyERC721( | ||||||
|  |         LibNFTOrder.ERC721Order calldata sellOrder, | ||||||
|  |         LibSignature.Signature calldata signature, | ||||||
|  |         bytes calldata callbackData | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         payable; | ||||||
|  |  | ||||||
|  |     /// @dev Cancel a single ERC721 order by its nonce. The caller | ||||||
|  |     ///      should be the maker of the order. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonce The order nonce. | ||||||
|  |     function cancelERC721Order(uint256 orderNonce) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Cancel multiple ERC721 orders by their nonces. The caller | ||||||
|  |     ///      should be the maker of the orders. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonces The order nonces. | ||||||
|  |     function batchCancelERC721Orders(uint256[] calldata orderNonces) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Buys multiple ERC721 assets by filling the | ||||||
|  |     ///      given orders. | ||||||
|  |     /// @param sellOrders The ERC721 sell orders. | ||||||
|  |     /// @param signatures The order signatures. | ||||||
|  |     /// @param callbackData The data (if any) to pass to the taker | ||||||
|  |     ///        callback for each order. Refer to the `callbackData` | ||||||
|  |     ///        parameter to for `buyERC721`. | ||||||
|  |     /// @param revertIfIncomplete If true, reverts if this | ||||||
|  |     ///        function fails to fill any individual order. | ||||||
|  |     /// @return successes An array of booleans corresponding to whether | ||||||
|  |     ///         each order in `orders` was successfully filled. | ||||||
|  |     function batchBuyERC721s( | ||||||
|  |         LibNFTOrder.ERC721Order[] calldata sellOrders, | ||||||
|  |         LibSignature.Signature[] calldata signatures, | ||||||
|  |         bytes[] calldata callbackData, | ||||||
|  |         bool revertIfIncomplete | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         payable | ||||||
|  |         returns (bool[] memory successes); | ||||||
|  |  | ||||||
|  |     /// @dev Matches a pair of complementary orders that have | ||||||
|  |     ///      a non-negative spread. Each order is filled at | ||||||
|  |     ///      their respective price, and the matcher receives | ||||||
|  |     ///      a profit denominated in the ERC20 token. | ||||||
|  |     /// @param sellOrder Order selling an ERC721 asset. | ||||||
|  |     /// @param buyOrder Order buying an ERC721 asset. | ||||||
|  |     /// @param sellOrderSignature Signature for the sell order. | ||||||
|  |     /// @param buyOrderSignature Signature for the buy order. | ||||||
|  |     /// @return profit The amount of profit earned by the caller | ||||||
|  |     ///         of this function (denominated in the ERC20 token | ||||||
|  |     ///         of the matched orders). | ||||||
|  |     function matchERC721Orders( | ||||||
|  |         LibNFTOrder.ERC721Order calldata sellOrder, | ||||||
|  |         LibNFTOrder.ERC721Order calldata buyOrder, | ||||||
|  |         LibSignature.Signature calldata sellOrderSignature, | ||||||
|  |         LibSignature.Signature calldata buyOrderSignature | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (uint256 profit); | ||||||
|  |  | ||||||
|  |     /// @dev Matches pairs of complementary orders that have | ||||||
|  |     ///      non-negative spreads. Each order is filled at | ||||||
|  |     ///      their respective price, and the matcher receives | ||||||
|  |     ///      a profit denominated in the ERC20 token. | ||||||
|  |     /// @param sellOrders Orders selling ERC721 assets. | ||||||
|  |     /// @param buyOrders Orders buying ERC721 assets. | ||||||
|  |     /// @param sellOrderSignatures Signatures for the sell orders. | ||||||
|  |     /// @param buyOrderSignatures Signatures for the buy orders. | ||||||
|  |     /// @return profits The amount of profit earned by the caller | ||||||
|  |     ///         of this function for each pair of matched orders | ||||||
|  |     ///         (denominated in the ERC20 token of the order pair). | ||||||
|  |     /// @return successes An array of booleans corresponding to | ||||||
|  |     ///         whether each pair of orders was successfully matched. | ||||||
|  |     function batchMatchERC721Orders( | ||||||
|  |         LibNFTOrder.ERC721Order[] calldata sellOrders, | ||||||
|  |         LibNFTOrder.ERC721Order[] calldata buyOrders, | ||||||
|  |         LibSignature.Signature[] calldata sellOrderSignatures, | ||||||
|  |         LibSignature.Signature[] calldata buyOrderSignatures | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (uint256[] memory profits, bool[] memory successes); | ||||||
|  |  | ||||||
|  |     /// @dev Callback for the ERC721 `safeTransferFrom` function. | ||||||
|  |     ///      This callback can be used to sell an ERC721 asset if | ||||||
|  |     ///      a valid ERC721 order, signature and `unwrapNativeToken` | ||||||
|  |     ///      are encoded in `data`. This allows takers to sell their | ||||||
|  |     ///      ERC721 asset without first calling `setApprovalForAll`. | ||||||
|  |     /// @param operator The address which called `safeTransferFrom`. | ||||||
|  |     /// @param from The address which previously owned the token. | ||||||
|  |     /// @param tokenId The ID of the asset being transferred. | ||||||
|  |     /// @param data Additional data with no specified format. If a | ||||||
|  |     ///        valid ERC721 order, signature and `unwrapNativeToken` | ||||||
|  |     ///        are encoded in `data`, this function will try to fill | ||||||
|  |     ///        the order using the received asset. | ||||||
|  |     /// @return success The selector of this function (0x150b7a02), | ||||||
|  |     ///         indicating that the callback succeeded. | ||||||
|  |     function onERC721Received( | ||||||
|  |         address operator, | ||||||
|  |         address from, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success); | ||||||
|  |  | ||||||
|  |     /// @dev Approves an ERC721 order on-chain. After pre-signing | ||||||
|  |     ///      the order, the `PRESIGNED` signature type will become | ||||||
|  |     ///      valid for that order and signer. | ||||||
|  |     /// @param order An ERC721 order. | ||||||
|  |     function preSignERC721Order(LibNFTOrder.ERC721Order calldata order) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @dev Checks whether the given signature is valid for the | ||||||
|  |     ///      the given ERC721 order. Reverts if not. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @param signature The signature to validate. | ||||||
|  |     function validateERC721OrderSignature( | ||||||
|  |         LibNFTOrder.ERC721Order calldata order, | ||||||
|  |         LibSignature.Signature calldata signature | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         view; | ||||||
|  |  | ||||||
|  |     /// @dev If the given order is buying an ERC721 asset, checks | ||||||
|  |     ///      whether or not the given token ID satisfies the required | ||||||
|  |     ///      properties specified in the order. If the order does not | ||||||
|  |     ///      specify any properties, this function instead checks | ||||||
|  |     ///      whether the given token ID matches the ID in the order. | ||||||
|  |     ///      Reverts if any checks fail, or if the order is selling | ||||||
|  |     ///      an ERC721 asset. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @param erc721TokenId The ID of the ERC721 asset. | ||||||
|  |     function validateERC721OrderProperties( | ||||||
|  |         LibNFTOrder.ERC721Order calldata order, | ||||||
|  |         uint256 erc721TokenId | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         view; | ||||||
|  |  | ||||||
|  |     /// @dev Get the current status of an ERC721 order. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @return status The status of the order. | ||||||
|  |     function getERC721OrderStatus(LibNFTOrder.ERC721Order calldata order) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderStatus status); | ||||||
|  |  | ||||||
|  |     /// @dev Get the EIP-712 hash of an ERC721 order. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @return orderHash The order hash. | ||||||
|  |     function getERC721OrderHash(LibNFTOrder.ERC721Order calldata order) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (bytes32 orderHash); | ||||||
|  |  | ||||||
|  |     /// @dev Get the order status bit vector for the given | ||||||
|  |     ///      maker address and nonce range. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     /// @param nonceRange Order status bit vectors are indexed | ||||||
|  |     ///        by maker address and the upper 248 bits of the | ||||||
|  |     ///        order nonce. We define `nonceRange` to be these | ||||||
|  |     ///        248 bits. | ||||||
|  |     /// @return bitVector The order status bit vector for the | ||||||
|  |     ///         given maker and nonce range. | ||||||
|  |     function getERC721OrderStatusBitVector(address maker, uint248 nonceRange) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (uint256 bitVector); | ||||||
|  | } | ||||||
							
								
								
									
										459
									
								
								contracts/zero-ex/contracts/src/features/libs/LibNFTOrder.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								contracts/zero-ex/contracts/src/features/libs/LibNFTOrder.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,459 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "../../vendor/IERC1155Token.sol"; | ||||||
|  | import "../../vendor/IERC721Token.sol"; | ||||||
|  | import "../../vendor/IPropertyValidator.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev A library for common NFT order operations. | ||||||
|  | library LibNFTOrder { | ||||||
|  |  | ||||||
|  |     enum OrderStatus { | ||||||
|  |         INVALID, | ||||||
|  |         FILLABLE, | ||||||
|  |         UNFILLABLE, | ||||||
|  |         EXPIRED | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     enum TradeDirection { | ||||||
|  |         SELL_NFT, | ||||||
|  |         BUY_NFT | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct Property { | ||||||
|  |         IPropertyValidator propertyValidator; | ||||||
|  |         bytes propertyData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct Fee { | ||||||
|  |         address recipient; | ||||||
|  |         uint256 amount; | ||||||
|  |         bytes feeData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // "Base struct" for ERC721Order and ERC1155, used | ||||||
|  |     // by the abstract contract `NFTOrders`. | ||||||
|  |     struct NFTOrder { | ||||||
|  |         TradeDirection direction; | ||||||
|  |         address maker; | ||||||
|  |         address taker; | ||||||
|  |         uint256 expiry; | ||||||
|  |         uint256 nonce; | ||||||
|  |         IERC20TokenV06 erc20Token; | ||||||
|  |         uint256 erc20TokenAmount; | ||||||
|  |         Fee[] fees; | ||||||
|  |         address nft; | ||||||
|  |         uint256 nftId; | ||||||
|  |         Property[] nftProperties; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // All fields align with those of NFTOrder | ||||||
|  |     struct ERC721Order { | ||||||
|  |         TradeDirection direction; | ||||||
|  |         address maker; | ||||||
|  |         address taker; | ||||||
|  |         uint256 expiry; | ||||||
|  |         uint256 nonce; | ||||||
|  |         IERC20TokenV06 erc20Token; | ||||||
|  |         uint256 erc20TokenAmount; | ||||||
|  |         Fee[] fees; | ||||||
|  |         IERC721Token erc721Token; | ||||||
|  |         uint256 erc721TokenId; | ||||||
|  |         Property[] erc721TokenProperties; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // All fields except `erc1155TokenAmount` align | ||||||
|  |     // with those of NFTOrder | ||||||
|  |     struct ERC1155Order { | ||||||
|  |         TradeDirection direction; | ||||||
|  |         address maker; | ||||||
|  |         address taker; | ||||||
|  |         uint256 expiry; | ||||||
|  |         uint256 nonce; | ||||||
|  |         IERC20TokenV06 erc20Token; | ||||||
|  |         uint256 erc20TokenAmount; | ||||||
|  |         Fee[] fees; | ||||||
|  |         IERC1155Token erc1155Token; | ||||||
|  |         uint256 erc1155TokenId; | ||||||
|  |         Property[] erc1155TokenProperties; | ||||||
|  |         // End of fields shared with NFTOrder | ||||||
|  |         uint128 erc1155TokenAmount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct OrderInfo { | ||||||
|  |         bytes32 orderHash; | ||||||
|  |         OrderStatus status; | ||||||
|  |         // `orderAmount` is 1 for all ERC721Orders, and | ||||||
|  |         // `erc1155TokenAmount` for ERC1155Orders. | ||||||
|  |         uint128 orderAmount; | ||||||
|  |         // The remaining amount of the ERC721/ERC1155 asset | ||||||
|  |         // that can be filled for the order. | ||||||
|  |         uint128 remainingAmount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // The type hash for ERC721 orders, which is: | ||||||
|  |     // keccak256(abi.encodePacked( | ||||||
|  |     //     "ERC721Order(", | ||||||
|  |     //       "uint8 direction,", | ||||||
|  |     //       "address maker,", | ||||||
|  |     //       "address taker,", | ||||||
|  |     //       "uint256 expiry,", | ||||||
|  |     //       "uint256 nonce,", | ||||||
|  |     //       "address erc20Token,", | ||||||
|  |     //       "uint256 erc20TokenAmount,", | ||||||
|  |     //       "Fee[] fees,", | ||||||
|  |     //       "address erc721Token,", | ||||||
|  |     //       "uint256 erc721TokenId,", | ||||||
|  |     //       "Property[] erc721TokenProperties", | ||||||
|  |     //     ")", | ||||||
|  |     //     "Fee(", | ||||||
|  |     //       "address recipient,", | ||||||
|  |     //       "uint256 amount,", | ||||||
|  |     //       "bytes feeData", | ||||||
|  |     //     ")", | ||||||
|  |     //     "Property(", | ||||||
|  |     //       "address propertyValidator,", | ||||||
|  |     //       "bytes propertyData", | ||||||
|  |     //     ")" | ||||||
|  |     // )) | ||||||
|  |     uint256 private constant _ERC_721_ORDER_TYPEHASH = | ||||||
|  |         0x2de32b2b090da7d8ab83ca4c85ba2eb6957bc7f6c50cb4ae1995e87560d808ed; | ||||||
|  |  | ||||||
|  |     // The type hash for ERC1155 orders, which is: | ||||||
|  |     // keccak256(abi.encodePacked( | ||||||
|  |     //     "ERC1155Order(", | ||||||
|  |     //       "uint8 direction,", | ||||||
|  |     //       "address maker,", | ||||||
|  |     //       "address taker,", | ||||||
|  |     //       "uint256 expiry,", | ||||||
|  |     //       "uint256 nonce,", | ||||||
|  |     //       "address erc20Token,", | ||||||
|  |     //       "uint256 erc20TokenAmount,", | ||||||
|  |     //       "Fee[] fees,", | ||||||
|  |     //       "address erc1155Token,", | ||||||
|  |     //       "uint256 erc1155TokenId,", | ||||||
|  |     //       "Property[] erc1155TokenProperties,", | ||||||
|  |     //       "uint128 erc1155TokenAmount", | ||||||
|  |     //     ")", | ||||||
|  |     //     "Fee(", | ||||||
|  |     //       "address recipient,", | ||||||
|  |     //       "uint256 amount,", | ||||||
|  |     //       "bytes feeData", | ||||||
|  |     //     ")", | ||||||
|  |     //     "Property(", | ||||||
|  |     //       "address propertyValidator,", | ||||||
|  |     //       "bytes propertyData", | ||||||
|  |     //     ")" | ||||||
|  |     // )) | ||||||
|  |     uint256 private constant _ERC_1155_ORDER_TYPEHASH = | ||||||
|  |         0x930490b1bcedd2e5139e22c761fafd52e533960197c2283f3922c7fd8c880be9; | ||||||
|  |  | ||||||
|  |     // keccak256(abi.encodePacked( | ||||||
|  |     //     "Fee(", | ||||||
|  |     //       "address recipient,", | ||||||
|  |     //       "uint256 amount,", | ||||||
|  |     //       "bytes feeData", | ||||||
|  |     //     ")" | ||||||
|  |     // )) | ||||||
|  |     uint256 private constant _FEE_TYPEHASH = | ||||||
|  |         0xe68c29f1b4e8cce0bbcac76eb1334bdc1dc1f293a517c90e9e532340e1e94115; | ||||||
|  |  | ||||||
|  |     // keccak256(abi.encodePacked( | ||||||
|  |     //     "Property(", | ||||||
|  |     //       "address propertyValidator,", | ||||||
|  |     //       "bytes propertyData", | ||||||
|  |     //     ")" | ||||||
|  |     // )) | ||||||
|  |     uint256 private constant _PROPERTY_TYPEHASH = | ||||||
|  |         0x6292cf854241cb36887e639065eca63b3af9f7f70270cebeda4c29b6d3bc65e8; | ||||||
|  |  | ||||||
|  |     // keccak256(""); | ||||||
|  |     bytes32 private constant _EMPTY_ARRAY_KECCAK256 = | ||||||
|  |         0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; | ||||||
|  |  | ||||||
|  |     // keccak256(abi.encodePacked(keccak256(abi.encode( | ||||||
|  |     //     _PROPERTY_TYPEHASH, | ||||||
|  |     //     address(0), | ||||||
|  |     //     keccak256("") | ||||||
|  |     // )))); | ||||||
|  |     bytes32 private constant _NULL_PROPERTY_STRUCT_HASH = | ||||||
|  |         0x720ee400a9024f6a49768142c339bf09d2dd9056ab52d20fbe7165faba6e142d; | ||||||
|  |  | ||||||
|  |     uint256 private constant ADDRESS_MASK = (1 << 160) - 1; | ||||||
|  |  | ||||||
|  |     // ERC721Order and NFTOrder fields are aligned, so | ||||||
|  |     // we can safely cast an ERC721Order to an NFTOrder. | ||||||
|  |     function asNFTOrder(ERC721Order memory erc721Order) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (NFTOrder memory nftOrder) | ||||||
|  |     { | ||||||
|  |         assembly { | ||||||
|  |             nftOrder := erc721Order | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // ERC1155Order and NFTOrder fields are aligned with | ||||||
|  |     // the exception of the last field `erc1155TokenAmount` | ||||||
|  |     // in ERC1155Order, so we can safely cast an ERC1155Order | ||||||
|  |     // to an NFTOrder. | ||||||
|  |     function asNFTOrder(ERC1155Order memory erc1155Order) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (NFTOrder memory nftOrder) | ||||||
|  |     { | ||||||
|  |         assembly { | ||||||
|  |             nftOrder := erc1155Order | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // ERC721Order and NFTOrder fields are aligned, so | ||||||
|  |     // we can safely cast an MFTOrder to an ERC721Order. | ||||||
|  |     function asERC721Order(NFTOrder memory nftOrder) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (ERC721Order memory erc721Order) | ||||||
|  |     { | ||||||
|  |         assembly { | ||||||
|  |             erc721Order := nftOrder | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // NOTE: This is only safe if `nftOrder` was previously | ||||||
|  |     // cast from an `ERC1155Order` and the original | ||||||
|  |     // `erc1155TokenAmount` memory word has not been corrupted! | ||||||
|  |     function asERC1155Order( | ||||||
|  |         NFTOrder memory nftOrder | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (ERC1155Order memory erc1155Order) | ||||||
|  |     { | ||||||
|  |         assembly { | ||||||
|  |             erc1155Order := nftOrder | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the struct hash of an ERC721 order. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @return structHash The struct hash of the order. | ||||||
|  |     function getERC721OrderStructHash(ERC721Order memory order) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes32 structHash) | ||||||
|  |     { | ||||||
|  |         bytes32 propertiesHash = _propertiesHash(order.erc721TokenProperties); | ||||||
|  |         bytes32 feesHash = _feesHash(order.fees); | ||||||
|  |  | ||||||
|  |         // Hash in place, equivalent to: | ||||||
|  |         // return keccak256(abi.encode( | ||||||
|  |         //     _ERC_721_ORDER_TYPEHASH, | ||||||
|  |         //     order.direction, | ||||||
|  |         //     order.maker, | ||||||
|  |         //     order.taker, | ||||||
|  |         //     order.expiry, | ||||||
|  |         //     order.nonce, | ||||||
|  |         //     order.erc20Token, | ||||||
|  |         //     order.erc20TokenAmount, | ||||||
|  |         //     feesHash, | ||||||
|  |         //     order.erc721Token, | ||||||
|  |         //     order.erc721TokenId, | ||||||
|  |         //     propertiesHash | ||||||
|  |         // )); | ||||||
|  |         assembly { | ||||||
|  |             if lt(order, 32) { invalid() } // Don't underflow memory. | ||||||
|  |  | ||||||
|  |             let typeHashPos := sub(order, 32) // order - 32 | ||||||
|  |             let feesHashPos := add(order, 224) // order + (32 * 7) | ||||||
|  |             let propertiesHashPos := add(order, 320) // order + (32 * 10) | ||||||
|  |  | ||||||
|  |             let typeHashMemBefore := mload(typeHashPos) | ||||||
|  |             let feeHashMemBefore := mload(feesHashPos) | ||||||
|  |             let propertiesHashMemBefore := mload(propertiesHashPos) | ||||||
|  |  | ||||||
|  |             mstore(typeHashPos, _ERC_721_ORDER_TYPEHASH) | ||||||
|  |             mstore(feesHashPos, feesHash) | ||||||
|  |             mstore(propertiesHashPos, propertiesHash) | ||||||
|  |             structHash := keccak256(typeHashPos, 384 /* 32 * 12 */ ) | ||||||
|  |  | ||||||
|  |             mstore(typeHashPos, typeHashMemBefore) | ||||||
|  |             mstore(feesHashPos, feeHashMemBefore) | ||||||
|  |             mstore(propertiesHashPos, propertiesHashMemBefore) | ||||||
|  |         } | ||||||
|  |         return structHash; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the struct hash of an ERC1155 order. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @return structHash The struct hash of the order. | ||||||
|  |     function getERC1155OrderStructHash(ERC1155Order memory order) | ||||||
|  |         internal | ||||||
|  |         pure | ||||||
|  |         returns (bytes32 structHash) | ||||||
|  |     { | ||||||
|  |         bytes32 propertiesHash = _propertiesHash(order.erc1155TokenProperties); | ||||||
|  |         bytes32 feesHash = _feesHash(order.fees); | ||||||
|  |  | ||||||
|  |         // Hash in place, equivalent to: | ||||||
|  |         // return keccak256(abi.encode( | ||||||
|  |         //     _ERC_1155_ORDER_TYPEHASH, | ||||||
|  |         //     order.direction, | ||||||
|  |         //     order.maker, | ||||||
|  |         //     order.taker, | ||||||
|  |         //     order.expiry, | ||||||
|  |         //     order.nonce, | ||||||
|  |         //     order.erc20Token, | ||||||
|  |         //     order.erc20TokenAmount, | ||||||
|  |         //     feesHash, | ||||||
|  |         //     order.erc1155Token, | ||||||
|  |         //     order.erc1155TokenId, | ||||||
|  |         //     propertiesHash, | ||||||
|  |         //     order.erc1155TokenAmount | ||||||
|  |         // )); | ||||||
|  |         assembly { | ||||||
|  |             if lt(order, 32) { invalid() } // Don't underflow memory. | ||||||
|  |  | ||||||
|  |             let typeHashPos := sub(order, 32) // order - 32 | ||||||
|  |             let feesHashPos := add(order, 224) // order + (32 * 7) | ||||||
|  |             let propertiesHashPos := add(order, 320) // order + (32 * 10) | ||||||
|  |  | ||||||
|  |             let typeHashMemBefore := mload(typeHashPos) | ||||||
|  |             let feesHashMemBefore := mload(feesHashPos) | ||||||
|  |             let propertiesHashMemBefore := mload(propertiesHashPos) | ||||||
|  |  | ||||||
|  |             mstore(typeHashPos, _ERC_1155_ORDER_TYPEHASH) | ||||||
|  |             mstore(feesHashPos, feesHash) | ||||||
|  |             mstore(propertiesHashPos, propertiesHash) | ||||||
|  |             structHash := keccak256(typeHashPos, 416 /* 32 * 12 */ ) | ||||||
|  |  | ||||||
|  |             mstore(typeHashPos, typeHashMemBefore) | ||||||
|  |             mstore(feesHashPos, feesHashMemBefore) | ||||||
|  |             mstore(propertiesHashPos, propertiesHashMemBefore) | ||||||
|  |         } | ||||||
|  |         return structHash; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Hashes the `properties` array as part of computing the | ||||||
|  |     // EIP-712 hash of an `ERC721Order` or `ERC1155Order`. | ||||||
|  |     function _propertiesHash(Property[] memory properties) | ||||||
|  |         private | ||||||
|  |         pure | ||||||
|  |         returns (bytes32 propertiesHash) | ||||||
|  |     { | ||||||
|  |         uint256 numProperties = properties.length; | ||||||
|  |         // We give `properties.length == 0` and `properties.length == 1` | ||||||
|  |         // special treatment because we expect these to be the most common. | ||||||
|  |         if (numProperties == 0) { | ||||||
|  |             propertiesHash = _EMPTY_ARRAY_KECCAK256; | ||||||
|  |         } else if (numProperties == 1) { | ||||||
|  |             Property memory property = properties[0]; | ||||||
|  |             if ( | ||||||
|  |                 address(property.propertyValidator) == address(0) && | ||||||
|  |                 property.propertyData.length == 0 | ||||||
|  |             ) { | ||||||
|  |                 propertiesHash = _NULL_PROPERTY_STRUCT_HASH; | ||||||
|  |             } else { | ||||||
|  |                 // propertiesHash = keccak256(abi.encodePacked(keccak256(abi.encode( | ||||||
|  |                 //     _PROPERTY_TYPEHASH, | ||||||
|  |                 //     properties[0].propertyValidator, | ||||||
|  |                 //     keccak256(properties[0].propertyData) | ||||||
|  |                 // )))); | ||||||
|  |                 bytes32 dataHash = keccak256(property.propertyData); | ||||||
|  |                 assembly { | ||||||
|  |                     // Load free memory pointer | ||||||
|  |                     let mem := mload(64) | ||||||
|  |                     mstore(mem, _PROPERTY_TYPEHASH) | ||||||
|  |                     // property.propertyValidator | ||||||
|  |                     mstore(add(mem, 32), and(ADDRESS_MASK, mload(property))) | ||||||
|  |                     // keccak256(property.propertyData) | ||||||
|  |                     mstore(add(mem, 64), dataHash) | ||||||
|  |                     mstore(mem, keccak256(mem, 96)) | ||||||
|  |                     propertiesHash := keccak256(mem, 32) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             bytes32[] memory propertyStructHashArray = new bytes32[](numProperties); | ||||||
|  |             for (uint256 i = 0; i < numProperties; i++) { | ||||||
|  |                 propertyStructHashArray[i] = keccak256(abi.encode( | ||||||
|  |                     _PROPERTY_TYPEHASH, | ||||||
|  |                     properties[i].propertyValidator, | ||||||
|  |                     keccak256(properties[i].propertyData) | ||||||
|  |                 )); | ||||||
|  |             } | ||||||
|  |             assembly { | ||||||
|  |                 propertiesHash := keccak256(add(propertyStructHashArray, 32), mul(numProperties, 32)) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Hashes the `fees` array as part of computing the | ||||||
|  |     // EIP-712 hash of an `ERC721Order` or `ERC1155Order`. | ||||||
|  |     function _feesHash(Fee[] memory fees) | ||||||
|  |         private | ||||||
|  |         pure | ||||||
|  |         returns (bytes32 feesHash) | ||||||
|  |     { | ||||||
|  |         uint256 numFees = fees.length; | ||||||
|  |         // We give `fees.length == 0` and `fees.length == 1` | ||||||
|  |         // special treatment because we expect these to be the most common. | ||||||
|  |         if (numFees == 0) { | ||||||
|  |             feesHash = _EMPTY_ARRAY_KECCAK256; | ||||||
|  |         } else if (numFees == 1) { | ||||||
|  |             // feesHash = keccak256(abi.encodePacked(keccak256(abi.encode( | ||||||
|  |             //     _FEE_TYPEHASH, | ||||||
|  |             //     fees[0].recipient, | ||||||
|  |             //     fees[0].amount, | ||||||
|  |             //     keccak256(fees[0].feeData) | ||||||
|  |             // )))); | ||||||
|  |             Fee memory fee = fees[0]; | ||||||
|  |             bytes32 dataHash = keccak256(fee.feeData); | ||||||
|  |             assembly { | ||||||
|  |                 // Load free memory pointer | ||||||
|  |                 let mem := mload(64) | ||||||
|  |                 mstore(mem, _FEE_TYPEHASH) | ||||||
|  |                 // fee.recipient | ||||||
|  |                 mstore(add(mem, 32), and(ADDRESS_MASK, mload(fee))) | ||||||
|  |                 // fee.amount | ||||||
|  |                 mstore(add(mem, 64), mload(add(fee, 32))) | ||||||
|  |                 // keccak256(fee.feeData) | ||||||
|  |                 mstore(add(mem, 96), dataHash) | ||||||
|  |                 mstore(mem, keccak256(mem, 128)) | ||||||
|  |                 feesHash := keccak256(mem, 32) | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             bytes32[] memory feeStructHashArray = new bytes32[](numFees); | ||||||
|  |             for (uint256 i = 0; i < numFees; i++) { | ||||||
|  |                 feeStructHashArray[i] = keccak256(abi.encode( | ||||||
|  |                     _FEE_TYPEHASH, | ||||||
|  |                     fees[i].recipient, | ||||||
|  |                     fees[i].amount, | ||||||
|  |                     keccak256(fees[i].feeData) | ||||||
|  |                 )); | ||||||
|  |             } | ||||||
|  |             assembly { | ||||||
|  |                 feesHash := keccak256(add(feeStructHashArray, 32), mul(numFees, 32)) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -44,7 +44,8 @@ library LibSignature { | |||||||
|         ILLEGAL, |         ILLEGAL, | ||||||
|         INVALID, |         INVALID, | ||||||
|         EIP712, |         EIP712, | ||||||
|         ETHSIGN |         ETHSIGN, | ||||||
|  |         PRESIGNED | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// @dev Encoded EC signature. |     /// @dev Encoded EC signature. | ||||||
| @@ -146,6 +147,15 @@ library LibSignature { | |||||||
|             ).rrevert(); |             ).rrevert(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // If a feature supports pre-signing, it wouldn't use  | ||||||
|  |         // `getSignerOfHash` on a pre-signed order. | ||||||
|  |         if (signature.signatureType == SignatureType.PRESIGNED) { | ||||||
|  |             LibSignatureRichErrors.SignatureValidationError( | ||||||
|  |                 LibSignatureRichErrors.SignatureValidationErrorCodes.UNSUPPORTED, | ||||||
|  |                 hash | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         // Solidity should check that the signature type is within enum range for us |         // Solidity should check that the signature type is within enum range for us | ||||||
|         // when abi-decoding. |         // when abi-decoding. | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -622,15 +622,6 @@ contract MultiplexFeature is | |||||||
|             _executeBatchSell(batchSellParams).boughtAmount; |             _executeBatchSell(batchSellParams).boughtAmount; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Transfers some amount of ETH to the given recipient and |  | ||||||
|     // reverts if the transfer fails. |  | ||||||
|     function _transferEth(address payable recipient, uint256 amount) |  | ||||||
|         private |  | ||||||
|     { |  | ||||||
|         (bool success,) = recipient.call{value: amount}(""); |  | ||||||
|         require(success, "MultiplexFeature::_transferEth/TRANSFER_FAILED"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // This function computes the "target" address of hop index `i` within |     // This function computes the "target" address of hop index `i` within | ||||||
|     // a multi-hop sell. |     // a multi-hop sell. | ||||||
|     // If `i == 0`, the target is the address which should hold the input |     // If `i == 0`, the target is the address which should hold the input | ||||||
|   | |||||||
| @@ -0,0 +1,635 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  | import "../../fixins/FixinERC1155Spender.sol"; | ||||||
|  | import "../../migrations/LibMigrate.sol"; | ||||||
|  | import "../../storage/LibERC1155OrdersStorage.sol"; | ||||||
|  | import "../interfaces/IFeature.sol"; | ||||||
|  | import "../interfaces/IERC1155OrdersFeature.sol"; | ||||||
|  | import "../libs/LibNFTOrder.sol"; | ||||||
|  | import "../libs/LibSignature.sol"; | ||||||
|  | import "./NFTOrders.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Feature for interacting with ERC1155 orders. | ||||||
|  | contract ERC1155OrdersFeature is | ||||||
|  |     IFeature, | ||||||
|  |     IERC1155OrdersFeature, | ||||||
|  |     FixinERC1155Spender, | ||||||
|  |     NFTOrders | ||||||
|  | { | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |     using LibSafeMathV06 for uint128; | ||||||
|  |     using LibNFTOrder for LibNFTOrder.ERC1155Order; | ||||||
|  |     using LibNFTOrder for LibNFTOrder.NFTOrder; | ||||||
|  |  | ||||||
|  |     /// @dev Name of this feature. | ||||||
|  |     string public constant override FEATURE_NAME = "ERC1155Orders"; | ||||||
|  |     /// @dev Version of this feature. | ||||||
|  |     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0); | ||||||
|  |  | ||||||
|  |     /// @dev The magic return value indicating the success of a `onERC1155Received`. | ||||||
|  |     bytes4 private constant ERC1155_RECEIVED_MAGIC_BYTES = this.onERC1155Received.selector; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     constructor(address zeroExAddress, IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         NFTOrders(zeroExAddress, weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     /// @dev Initialize and register this feature. | ||||||
|  |     ///      Should be delegatecalled by `Migrate.migrate()`. | ||||||
|  |     /// @return success `LibMigrate.SUCCESS` on success. | ||||||
|  |     function migrate() | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success) | ||||||
|  |     { | ||||||
|  |         _registerFeatureFunction(this.sellERC1155.selector); | ||||||
|  |         _registerFeatureFunction(this.buyERC1155.selector); | ||||||
|  |         _registerFeatureFunction(this.cancelERC1155Order.selector); | ||||||
|  |         _registerFeatureFunction(this.batchBuyERC1155s.selector); | ||||||
|  |         _registerFeatureFunction(this.onERC1155Received.selector); | ||||||
|  |         _registerFeatureFunction(this.preSignERC1155Order.selector); | ||||||
|  |         _registerFeatureFunction(this.validateERC1155OrderSignature.selector); | ||||||
|  |         _registerFeatureFunction(this.validateERC1155OrderProperties.selector); | ||||||
|  |         _registerFeatureFunction(this.getERC1155OrderInfo.selector); | ||||||
|  |         _registerFeatureFunction(this.getERC1155OrderHash.selector); | ||||||
|  |         return LibMigrate.MIGRATE_SUCCESS; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Sells an ERC1155 asset to fill the given order. | ||||||
|  |     /// @param buyOrder The ERC1155 buy order. | ||||||
|  |     /// @param signature The order signature from the maker. | ||||||
|  |     /// @param erc1155TokenId The ID of the ERC1155 asset being | ||||||
|  |     ///        sold. If the given order specifies properties, | ||||||
|  |     ///        the asset must satisfy those properties. Otherwise, | ||||||
|  |     ///        it must equal the tokenId in the order. | ||||||
|  |     /// @param erc1155SellAmount The amount of the ERC1155 asset | ||||||
|  |     ///        to sell. | ||||||
|  |     /// @param unwrapNativeToken If this parameter is true and the | ||||||
|  |     ///        ERC20 token of the order is e.g. WETH, unwraps the | ||||||
|  |     ///        token before transferring it to the taker. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC1155OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC20 tokens have been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC1155 asset to the buyer. | ||||||
|  |     function sellERC1155( | ||||||
|  |         LibNFTOrder.ERC1155Order memory buyOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         uint256 erc1155TokenId, | ||||||
|  |         uint128 erc1155SellAmount, | ||||||
|  |         bool unwrapNativeToken, | ||||||
|  |         bytes memory callbackData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         _sellERC1155( | ||||||
|  |             buyOrder, | ||||||
|  |             signature, | ||||||
|  |             SellParams( | ||||||
|  |                 erc1155SellAmount, | ||||||
|  |                 erc1155TokenId, | ||||||
|  |                 unwrapNativeToken, | ||||||
|  |                 msg.sender, // taker | ||||||
|  |                 msg.sender, // owner | ||||||
|  |                 callbackData | ||||||
|  |             ) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Buys an ERC1155 asset by filling the given order. | ||||||
|  |     /// @param sellOrder The ERC1155 sell order. | ||||||
|  |     /// @param signature The order signature. | ||||||
|  |     /// @param erc1155BuyAmount The amount of the ERC1155 asset | ||||||
|  |     ///        to buy. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC1155OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC1155 asset has been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC20 tokens to the seller. | ||||||
|  |     ///        Native tokens acquired during the callback can be used | ||||||
|  |     ///        to fill the order. | ||||||
|  |     function buyERC1155( | ||||||
|  |         LibNFTOrder.ERC1155Order memory sellOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         uint128 erc1155BuyAmount, | ||||||
|  |         bytes memory callbackData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         payable | ||||||
|  |     { | ||||||
|  |         uint256 ethBalanceBefore = address(this).balance | ||||||
|  |             .safeSub(msg.value); | ||||||
|  |         _buyERC1155( | ||||||
|  |             sellOrder, | ||||||
|  |             signature, | ||||||
|  |             BuyParams( | ||||||
|  |                 erc1155BuyAmount, | ||||||
|  |                 msg.value, | ||||||
|  |                 callbackData | ||||||
|  |             ) | ||||||
|  |         ); | ||||||
|  |         uint256 ethBalanceAfter = address(this).balance; | ||||||
|  |         // Cannot use pre-existing ETH balance | ||||||
|  |         if (ethBalanceAfter < ethBalanceBefore) { | ||||||
|  |             LibNFTOrdersRichErrors.OverspentEthError( | ||||||
|  |                 ethBalanceBefore - ethBalanceAfter + msg.value, | ||||||
|  |                 msg.value | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |         // Refund | ||||||
|  |         _transferEth(msg.sender, ethBalanceAfter - ethBalanceBefore); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Cancel a single ERC1155 order by its nonce. The caller | ||||||
|  |     ///      should be the maker of the order. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonce The order nonce. | ||||||
|  |     function cancelERC1155Order(uint256 orderNonce) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         // The bitvector is indexed by the lower 8 bits of the nonce. | ||||||
|  |         uint256 flag = 1 << (orderNonce & 255); | ||||||
|  |         // Update order cancellation bit vector to indicate that the order | ||||||
|  |         // has been cancelled/filled by setting the designated bit to 1. | ||||||
|  |         LibERC1155OrdersStorage.getStorage().orderCancellationByMaker | ||||||
|  |             [msg.sender][uint248(orderNonce >> 8)] |= flag; | ||||||
|  |  | ||||||
|  |         emit ERC1155OrderCancelled(msg.sender, orderNonce); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Cancel multiple ERC1155 orders by their nonces. The caller | ||||||
|  |     ///      should be the maker of the orders. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonces The order nonces. | ||||||
|  |     function batchCancelERC1155Orders(uint256[] calldata orderNonces) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         for (uint256 i = 0; i < orderNonces.length; i++) { | ||||||
|  |             cancelERC1155Order(orderNonces[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Buys multiple ERC1155 assets by filling the | ||||||
|  |     ///      given orders. | ||||||
|  |     /// @param sellOrders The ERC1155 sell orders. | ||||||
|  |     /// @param signatures The order signatures. | ||||||
|  |     /// @param erc1155FillAmounts The amounts of the ERC1155 assets | ||||||
|  |     ///        to buy for each order. | ||||||
|  |     /// @param callbackData The data (if any) to pass to the taker | ||||||
|  |     ///        callback for each order. Refer to the `callbackData` | ||||||
|  |     ///        parameter to for `buyERC1155`. | ||||||
|  |     /// @param revertIfIncomplete If true, reverts if this | ||||||
|  |     ///        function fails to fill any individual order. | ||||||
|  |     /// @return successes An array of booleans corresponding to whether | ||||||
|  |     ///         each order in `orders` was successfully filled. | ||||||
|  |     function batchBuyERC1155s( | ||||||
|  |         LibNFTOrder.ERC1155Order[] memory sellOrders, | ||||||
|  |         LibSignature.Signature[] memory signatures, | ||||||
|  |         uint128[] calldata erc1155FillAmounts, | ||||||
|  |         bytes[] memory callbackData, | ||||||
|  |         bool revertIfIncomplete | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         payable | ||||||
|  |         returns (bool[] memory successes) | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             sellOrders.length == signatures.length && | ||||||
|  |             sellOrders.length == erc1155FillAmounts.length && | ||||||
|  |             sellOrders.length == callbackData.length, | ||||||
|  |             "ERC1155OrdersFeature::batchBuyERC1155s/ARRAY_LENGTH_MISMATCH" | ||||||
|  |         ); | ||||||
|  |         successes = new bool[](sellOrders.length); | ||||||
|  |  | ||||||
|  |         uint256 ethBalanceBefore = address(this).balance | ||||||
|  |             .safeSub(msg.value); | ||||||
|  |         if (revertIfIncomplete) { | ||||||
|  |             for (uint256 i = 0; i < sellOrders.length; i++) { | ||||||
|  |                 // Will revert if _buyERC1155 reverts. | ||||||
|  |                 _buyERC1155( | ||||||
|  |                     sellOrders[i], | ||||||
|  |                     signatures[i], | ||||||
|  |                     BuyParams( | ||||||
|  |                         erc1155FillAmounts[i], | ||||||
|  |                         address(this).balance.safeSub(ethBalanceBefore), // Remaining ETH available | ||||||
|  |                         callbackData[i] | ||||||
|  |                     ) | ||||||
|  |                 ); | ||||||
|  |                 successes[i] = true; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             for (uint256 i = 0; i < sellOrders.length; i++) { | ||||||
|  |                 // Delegatecall `_buyERC1155` to catch swallow reverts while | ||||||
|  |                 // preserving execution context. | ||||||
|  |                 // Note that `_buyERC1155` is a public function but should _not_ | ||||||
|  |                 // be registered in the Exchange Proxy. | ||||||
|  |                 (successes[i], ) = _implementation.delegatecall( | ||||||
|  |                     abi.encodeWithSelector( | ||||||
|  |                         this._buyERC1155.selector, | ||||||
|  |                         sellOrders[i], | ||||||
|  |                         signatures[i], | ||||||
|  |                         BuyParams( | ||||||
|  |                             erc1155FillAmounts[i], | ||||||
|  |                             address(this).balance.safeSub(ethBalanceBefore), // Remaining ETH available | ||||||
|  |                             callbackData[i] | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Cannot use pre-existing ETH balance | ||||||
|  |         uint256 ethBalanceAfter = address(this).balance; | ||||||
|  |         if (ethBalanceAfter < ethBalanceBefore) { | ||||||
|  |             LibNFTOrdersRichErrors.OverspentEthError( | ||||||
|  |                 msg.value + (ethBalanceBefore - ethBalanceAfter), | ||||||
|  |                 msg.value | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Refund | ||||||
|  |         _transferEth(msg.sender, ethBalanceAfter - ethBalanceBefore); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Callback for the ERC1155 `safeTransferFrom` function. | ||||||
|  |     ///      This callback can be used to sell an ERC1155 asset if | ||||||
|  |     ///      a valid ERC1155 order, signature and `unwrapNativeToken` | ||||||
|  |     ///      are encoded in `data`. This allows takers to sell their | ||||||
|  |     ///      ERC1155 asset without first calling `setApprovalForAll`. | ||||||
|  |     /// @param operator The address which called `safeTransferFrom`. | ||||||
|  |     /// @param tokenId The ID of the asset being transferred. | ||||||
|  |     /// @param value The amount being transferred. | ||||||
|  |     /// @param data Additional data with no specified format. If a | ||||||
|  |     ///        valid ERC1155 order, signature and `unwrapNativeToken` | ||||||
|  |     ///        are encoded in `data`, this function will try to fill | ||||||
|  |     ///        the order using the received asset. | ||||||
|  |     /// @return success The selector of this function (0xf23a6e61), | ||||||
|  |     ///         indicating that the callback succeeded. | ||||||
|  |     function onERC1155Received( | ||||||
|  |         address operator, | ||||||
|  |         address /* from */, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 value, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         returns (bytes4 success) | ||||||
|  |     { | ||||||
|  |         // Decode the order, signature, and `unwrapNativeToken` from | ||||||
|  |         // `data`. If `data` does not encode such parameters, this | ||||||
|  |         // will throw. | ||||||
|  |         ( | ||||||
|  |             LibNFTOrder.ERC1155Order memory buyOrder, | ||||||
|  |             LibSignature.Signature memory signature, | ||||||
|  |             bool unwrapNativeToken | ||||||
|  |         ) = abi.decode( | ||||||
|  |             data, | ||||||
|  |             (LibNFTOrder.ERC1155Order, LibSignature.Signature, bool) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // `onERC1155Received` is called by the ERC1155 token contract. | ||||||
|  |         // Check that it matches the ERC1155 token in the order. | ||||||
|  |         if (msg.sender != address(buyOrder.erc1155Token)) { | ||||||
|  |             LibNFTOrdersRichErrors.ERC1155TokenMismatchError( | ||||||
|  |                 msg.sender, | ||||||
|  |                 address(buyOrder.erc1155Token) | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         _sellERC1155( | ||||||
|  |             buyOrder, | ||||||
|  |             signature, | ||||||
|  |             SellParams( | ||||||
|  |                 value.safeDowncastToUint128(), | ||||||
|  |                 tokenId, | ||||||
|  |                 unwrapNativeToken, | ||||||
|  |                 operator,       // taker | ||||||
|  |                 address(this),  // owner (we hold the NFT currently) | ||||||
|  |                 new bytes(0)    // No taker callback | ||||||
|  |             ) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         return ERC1155_RECEIVED_MAGIC_BYTES; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Approves an ERC1155 order on-chain. After pre-signing | ||||||
|  |     ///      the order, the `PRESIGNED` signature type will become | ||||||
|  |     ///      valid for that order and signer. | ||||||
|  |     /// @param order An ERC1155 order. | ||||||
|  |     function preSignERC1155Order(LibNFTOrder.ERC1155Order memory order) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             order.maker == msg.sender, | ||||||
|  |             "ERC1155OrdersFeature::preSignERC1155Order/MAKER_MISMATCH" | ||||||
|  |         ); | ||||||
|  |         bytes32 orderHash = getERC1155OrderHash(order); | ||||||
|  |  | ||||||
|  |         LibERC1155OrdersStorage.Storage storage stor = | ||||||
|  |             LibERC1155OrdersStorage.getStorage(); | ||||||
|  |         // Set `preSigned` to true on the order state variable | ||||||
|  |         // to indicate that the order has been pre-signed. | ||||||
|  |         stor.orderState[orderHash].preSigned = true; | ||||||
|  |  | ||||||
|  |         emit ERC1155OrderPreSigned( | ||||||
|  |             order.direction, | ||||||
|  |             order.maker, | ||||||
|  |             order.taker, | ||||||
|  |             order.expiry, | ||||||
|  |             order.nonce, | ||||||
|  |             order.erc20Token, | ||||||
|  |             order.erc20TokenAmount, | ||||||
|  |             order.fees, | ||||||
|  |             order.erc1155Token, | ||||||
|  |             order.erc1155TokenId, | ||||||
|  |             order.erc1155TokenProperties, | ||||||
|  |             order.erc1155TokenAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Core settlement logic for selling an ERC1155 asset. | ||||||
|  |     // Used by `sellERC1155` and `onERC1155Received`. | ||||||
|  |     function _sellERC1155( | ||||||
|  |         LibNFTOrder.ERC1155Order memory buyOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         SellParams memory params | ||||||
|  |     ) | ||||||
|  |         private | ||||||
|  |     { | ||||||
|  |         uint256 erc20FillAmount = _sellNFT( | ||||||
|  |             buyOrder.asNFTOrder(), | ||||||
|  |             signature, | ||||||
|  |             params | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         emit ERC1155OrderFilled( | ||||||
|  |             buyOrder.direction, | ||||||
|  |             buyOrder.maker, | ||||||
|  |             params.taker, | ||||||
|  |             buyOrder.nonce, | ||||||
|  |             buyOrder.erc20Token, | ||||||
|  |             erc20FillAmount, | ||||||
|  |             buyOrder.erc1155Token, | ||||||
|  |             params.tokenId, | ||||||
|  |             params.sellAmount, | ||||||
|  |             address(0) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Core settlement logic for buying an ERC1155 asset. | ||||||
|  |     // Used by `buyERC1155` and `batchBuyERC1155s`. | ||||||
|  |     function _buyERC1155( | ||||||
|  |         LibNFTOrder.ERC1155Order memory sellOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         BuyParams memory params | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         payable | ||||||
|  |     { | ||||||
|  |         uint256 erc20FillAmount = _buyNFT( | ||||||
|  |             sellOrder.asNFTOrder(), | ||||||
|  |             signature, | ||||||
|  |             params | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         emit ERC1155OrderFilled( | ||||||
|  |             sellOrder.direction, | ||||||
|  |             sellOrder.maker, | ||||||
|  |             msg.sender, | ||||||
|  |             sellOrder.nonce, | ||||||
|  |             sellOrder.erc20Token, | ||||||
|  |             erc20FillAmount, | ||||||
|  |             sellOrder.erc1155Token, | ||||||
|  |             sellOrder.erc1155TokenId, | ||||||
|  |             params.buyAmount, | ||||||
|  |             address(0) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Checks whether the given signature is valid for the | ||||||
|  |     ///      the given ERC1155 order. Reverts if not. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @param signature The signature to validate. | ||||||
|  |     function validateERC1155OrderSignature( | ||||||
|  |         LibNFTOrder.ERC1155Order memory order, | ||||||
|  |         LibSignature.Signature memory signature | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         bytes32 orderHash = getERC1155OrderHash(order); | ||||||
|  |         _validateOrderSignature(orderHash, signature, order.maker); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Validates that the given signature is valid for the | ||||||
|  |     ///      given maker and order hash. Reverts if the signature | ||||||
|  |     ///      is not valid. | ||||||
|  |     /// @param orderHash The hash of the order that was signed. | ||||||
|  |     /// @param signature The signature to check. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     function _validateOrderSignature( | ||||||
|  |         bytes32 orderHash, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         address maker | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         if (signature.signatureType == LibSignature.SignatureType.PRESIGNED) { | ||||||
|  |             // Check if order hash has been pre-signed by the maker. | ||||||
|  |             bool isPreSigned = LibERC1155OrdersStorage.getStorage() | ||||||
|  |                 .orderState[orderHash].preSigned; | ||||||
|  |             if (!isPreSigned) { | ||||||
|  |                 LibNFTOrdersRichErrors.InvalidSignerError(maker, address(0)).rrevert(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             address signer = LibSignature.getSignerOfHash(orderHash, signature); | ||||||
|  |             if (signer != maker) { | ||||||
|  |                 LibNFTOrdersRichErrors.InvalidSignerError(maker, signer).rrevert(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Transfers an NFT asset. | ||||||
|  |     /// @param token The address of the NFT contract. | ||||||
|  |     /// @param from The address currently holding the asset. | ||||||
|  |     /// @param to The address to transfer the asset to. | ||||||
|  |     /// @param tokenId The ID of the asset to transfer. | ||||||
|  |     /// @param amount The amount of the asset to transfer. Always | ||||||
|  |     ///        1 for ERC721 assets. | ||||||
|  |     function _transferNFTAssetFrom( | ||||||
|  |         address token, | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 amount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         _transferERC1155AssetFrom(IERC1155Token(token), from, to, tokenId, amount); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Updates storage to indicate that the given order | ||||||
|  |     ///      has been filled by the given amount. | ||||||
|  |     /// @param orderHash The hash of `order`. | ||||||
|  |     /// @param fillAmount The amount (denominated in the NFT asset) | ||||||
|  |     ///        that the order has been filled by. | ||||||
|  |     function _updateOrderState( | ||||||
|  |         LibNFTOrder.NFTOrder memory /* order */, | ||||||
|  |         bytes32 orderHash, | ||||||
|  |         uint128 fillAmount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         LibERC1155OrdersStorage.Storage storage stor = LibERC1155OrdersStorage.getStorage(); | ||||||
|  |         uint128 filledAmount = stor.orderState[orderHash].filledAmount; | ||||||
|  |         // Filled amount should never overflow 128 bits | ||||||
|  |         assert(filledAmount + fillAmount > filledAmount); | ||||||
|  |         stor.orderState[orderHash].filledAmount = filledAmount + fillAmount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev If the given order is buying an ERC1155 asset, checks | ||||||
|  |     ///      whether or not the given token ID satisfies the required | ||||||
|  |     ///      properties specified in the order. If the order does not | ||||||
|  |     ///      specify any properties, this function instead checks | ||||||
|  |     ///      whether the given token ID matches the ID in the order. | ||||||
|  |     ///      Reverts if any checks fail, or if the order is selling | ||||||
|  |     ///      an ERC1155 asset. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @param erc1155TokenId The ID of the ERC1155 asset. | ||||||
|  |     function validateERC1155OrderProperties( | ||||||
|  |         LibNFTOrder.ERC1155Order memory order, | ||||||
|  |         uint256 erc1155TokenId | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         _validateOrderProperties( | ||||||
|  |             order.asNFTOrder(), | ||||||
|  |             erc1155TokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the order info for an ERC1155 order. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @return orderInfo Info about the order. | ||||||
|  |     function getERC1155OrderInfo(LibNFTOrder.ERC1155Order memory order) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderInfo memory orderInfo) | ||||||
|  |     { | ||||||
|  |         orderInfo.orderAmount = order.erc1155TokenAmount; | ||||||
|  |         orderInfo.orderHash = getERC1155OrderHash(order); | ||||||
|  |  | ||||||
|  |         // Only buy orders with `erc1155TokenId` == 0 can be property | ||||||
|  |         // orders. | ||||||
|  |         if (order.erc1155TokenProperties.length > 0 && | ||||||
|  |                 (order.direction != LibNFTOrder.TradeDirection.BUY_NFT || | ||||||
|  |                  order.erc1155TokenId != 0)) | ||||||
|  |         { | ||||||
|  |             orderInfo.status = LibNFTOrder.OrderStatus.INVALID; | ||||||
|  |             return orderInfo; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Buy orders cannot use ETH as the ERC20 token, since ETH cannot be | ||||||
|  |         // transferred from the buyer by a contract. | ||||||
|  |         if (order.direction == LibNFTOrder.TradeDirection.BUY_NFT && | ||||||
|  |             address(order.erc20Token) == NATIVE_TOKEN_ADDRESS) | ||||||
|  |         { | ||||||
|  |             orderInfo.status = LibNFTOrder.OrderStatus.INVALID; | ||||||
|  |             return orderInfo; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check for expiry. | ||||||
|  |         if (order.expiry <= block.timestamp) { | ||||||
|  |             orderInfo.status = LibNFTOrder.OrderStatus.EXPIRED; | ||||||
|  |             return orderInfo; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         { | ||||||
|  |             LibERC1155OrdersStorage.Storage storage stor = | ||||||
|  |                 LibERC1155OrdersStorage.getStorage(); | ||||||
|  |  | ||||||
|  |             LibERC1155OrdersStorage.OrderState storage orderState = | ||||||
|  |                 stor.orderState[orderInfo.orderHash]; | ||||||
|  |             orderInfo.remainingAmount = order.erc1155TokenAmount | ||||||
|  |                 .safeSub128(orderState.filledAmount); | ||||||
|  |  | ||||||
|  |             // `orderCancellationByMaker` is indexed by maker and nonce. | ||||||
|  |             uint256 orderCancellationBitVector = | ||||||
|  |                 stor.orderCancellationByMaker[order.maker][uint248(order.nonce >> 8)]; | ||||||
|  |             // The bitvector is indexed by the lower 8 bits of the nonce. | ||||||
|  |             uint256 flag = 1 << (order.nonce & 255); | ||||||
|  |  | ||||||
|  |             if (orderInfo.remainingAmount == 0 || | ||||||
|  |                 orderCancellationBitVector & flag != 0) | ||||||
|  |             { | ||||||
|  |                 orderInfo.status = LibNFTOrder.OrderStatus.UNFILLABLE; | ||||||
|  |                 return orderInfo; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Otherwise, the order is fillable. | ||||||
|  |         orderInfo.status = LibNFTOrder.OrderStatus.FILLABLE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the order info for an NFT order. | ||||||
|  |     /// @param order The NFT order. | ||||||
|  |     /// @return orderInfo Info about the order. | ||||||
|  |     function _getOrderInfo(LibNFTOrder.NFTOrder memory order) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderInfo memory orderInfo) | ||||||
|  |     { | ||||||
|  |         return getERC1155OrderInfo(order.asERC1155Order()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the EIP-712 hash of an ERC1155 order. | ||||||
|  |     /// @param order The ERC1155 order. | ||||||
|  |     /// @return orderHash The order hash. | ||||||
|  |     function getERC1155OrderHash(LibNFTOrder.ERC1155Order memory order) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (bytes32 orderHash) | ||||||
|  |     { | ||||||
|  |         return _getEIP712Hash(LibNFTOrder.getERC1155OrderStructHash(order)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,931 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  | import "../../fixins/FixinERC721Spender.sol"; | ||||||
|  | import "../../migrations/LibMigrate.sol"; | ||||||
|  | import "../../storage/LibERC721OrdersStorage.sol"; | ||||||
|  | import "../interfaces/IFeature.sol"; | ||||||
|  | import "../interfaces/IERC721OrdersFeature.sol"; | ||||||
|  | import "../libs/LibNFTOrder.sol"; | ||||||
|  | import "../libs/LibSignature.sol"; | ||||||
|  | import "./NFTOrders.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Feature for interacting with ERC721 orders. | ||||||
|  | contract ERC721OrdersFeature is | ||||||
|  |     IFeature, | ||||||
|  |     IERC721OrdersFeature, | ||||||
|  |     FixinERC721Spender, | ||||||
|  |     NFTOrders | ||||||
|  | { | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |     using LibNFTOrder for LibNFTOrder.ERC721Order; | ||||||
|  |     using LibNFTOrder for LibNFTOrder.NFTOrder; | ||||||
|  |  | ||||||
|  |     /// @dev Name of this feature. | ||||||
|  |     string public constant override FEATURE_NAME = "ERC721Orders"; | ||||||
|  |     /// @dev Version of this feature. | ||||||
|  |     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0); | ||||||
|  |  | ||||||
|  |     /// @dev The magic return value indicating the success of a `onERC721Received`. | ||||||
|  |     bytes4 private constant ERC721_RECEIVED_MAGIC_BYTES = this.onERC721Received.selector; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     constructor(address zeroExAddress, IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         NFTOrders(zeroExAddress, weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     /// @dev Initialize and register this feature. | ||||||
|  |     ///      Should be delegatecalled by `Migrate.migrate()`. | ||||||
|  |     /// @return success `LibMigrate.SUCCESS` on success. | ||||||
|  |     function migrate() | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success) | ||||||
|  |     { | ||||||
|  |         _registerFeatureFunction(this.sellERC721.selector); | ||||||
|  |         _registerFeatureFunction(this.buyERC721.selector); | ||||||
|  |         _registerFeatureFunction(this.cancelERC721Order.selector); | ||||||
|  |         _registerFeatureFunction(this.batchBuyERC721s.selector); | ||||||
|  |         _registerFeatureFunction(this.matchERC721Orders.selector); | ||||||
|  |         _registerFeatureFunction(this.batchMatchERC721Orders.selector); | ||||||
|  |         _registerFeatureFunction(this.onERC721Received.selector); | ||||||
|  |         _registerFeatureFunction(this.preSignERC721Order.selector); | ||||||
|  |         _registerFeatureFunction(this.validateERC721OrderSignature.selector); | ||||||
|  |         _registerFeatureFunction(this.validateERC721OrderProperties.selector); | ||||||
|  |         _registerFeatureFunction(this.getERC721OrderStatus.selector); | ||||||
|  |         _registerFeatureFunction(this.getERC721OrderHash.selector); | ||||||
|  |         _registerFeatureFunction(this.getERC721OrderStatusBitVector.selector); | ||||||
|  |         return LibMigrate.MIGRATE_SUCCESS; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Sells an ERC721 asset to fill the given order. | ||||||
|  |     /// @param buyOrder The ERC721 buy order. | ||||||
|  |     /// @param signature The order signature from the maker. | ||||||
|  |     /// @param erc721TokenId The ID of the ERC721 asset being | ||||||
|  |     ///        sold. If the given order specifies properties, | ||||||
|  |     ///        the asset must satisfy those properties. Otherwise, | ||||||
|  |     ///        it must equal the tokenId in the order. | ||||||
|  |     /// @param unwrapNativeToken If this parameter is true and the | ||||||
|  |     ///        ERC20 token of the order is e.g. WETH, unwraps the | ||||||
|  |     ///        token before transferring it to the taker. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC721OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC20 tokens have been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC721 asset to the buyer. | ||||||
|  |     function sellERC721( | ||||||
|  |         LibNFTOrder.ERC721Order memory buyOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         uint256 erc721TokenId, | ||||||
|  |         bool unwrapNativeToken, | ||||||
|  |         bytes memory callbackData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         _sellERC721( | ||||||
|  |             buyOrder, | ||||||
|  |             signature, | ||||||
|  |             erc721TokenId, | ||||||
|  |             unwrapNativeToken, | ||||||
|  |             msg.sender, // taker | ||||||
|  |             msg.sender, // owner | ||||||
|  |             callbackData | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Buys an ERC721 asset by filling the given order. | ||||||
|  |     /// @param sellOrder The ERC721 sell order. | ||||||
|  |     /// @param signature The order signature. | ||||||
|  |     /// @param callbackData If this parameter is non-zero, invokes | ||||||
|  |     ///        `zeroExERC721OrderCallback` on `msg.sender` after | ||||||
|  |     ///        the ERC721 asset has been transferred to `msg.sender` | ||||||
|  |     ///        but before transferring the ERC20 tokens to the seller. | ||||||
|  |     ///        Native tokens acquired during the callback can be used | ||||||
|  |     ///        to fill the order. | ||||||
|  |     function buyERC721( | ||||||
|  |         LibNFTOrder.ERC721Order memory sellOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         bytes memory callbackData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         payable | ||||||
|  |     { | ||||||
|  |         uint256 ethBalanceBefore = address(this).balance | ||||||
|  |             .safeSub(msg.value); | ||||||
|  |         _buyERC721( | ||||||
|  |             sellOrder, | ||||||
|  |             signature, | ||||||
|  |             msg.value, | ||||||
|  |             callbackData | ||||||
|  |         ); | ||||||
|  |         uint256 ethBalanceAfter = address(this).balance; | ||||||
|  |         // Cannot use pre-existing ETH balance | ||||||
|  |         if (ethBalanceAfter < ethBalanceBefore) { | ||||||
|  |             LibNFTOrdersRichErrors.OverspentEthError( | ||||||
|  |                 msg.value + (ethBalanceBefore - ethBalanceAfter), | ||||||
|  |                 msg.value | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |         // Refund | ||||||
|  |         _transferEth(msg.sender, ethBalanceAfter - ethBalanceBefore); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Cancel a single ERC721 order by its nonce. The caller | ||||||
|  |     ///      should be the maker of the order. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonce The order nonce. | ||||||
|  |     function cancelERC721Order(uint256 orderNonce) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         // Mark order as cancelled | ||||||
|  |         _setOrderStatusBit(msg.sender, orderNonce); | ||||||
|  |         emit ERC721OrderCancelled(msg.sender, orderNonce); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Cancel multiple ERC721 orders by their nonces. The caller | ||||||
|  |     ///      should be the maker of the orders. Silently succeeds if | ||||||
|  |     ///      an order with the same nonce has already been filled or | ||||||
|  |     ///      cancelled. | ||||||
|  |     /// @param orderNonces The order nonces. | ||||||
|  |     function batchCancelERC721Orders(uint256[] calldata orderNonces) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         for (uint256 i = 0; i < orderNonces.length; i++) { | ||||||
|  |             cancelERC721Order(orderNonces[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Buys multiple ERC721 assets by filling the | ||||||
|  |     ///      given orders. | ||||||
|  |     /// @param sellOrders The ERC721 sell orders. | ||||||
|  |     /// @param signatures The order signatures. | ||||||
|  |     /// @param revertIfIncomplete If true, reverts if this | ||||||
|  |     ///        function fails to fill any individual order. | ||||||
|  |     /// @param callbackData The data (if any) to pass to the taker | ||||||
|  |     ///        callback for each order. Refer to the `callbackData` | ||||||
|  |     ///        parameter to for `buyERC721`. | ||||||
|  |     /// @return successes An array of booleans corresponding to whether | ||||||
|  |     ///         each order in `orders` was successfully filled. | ||||||
|  |     function batchBuyERC721s( | ||||||
|  |         LibNFTOrder.ERC721Order[] memory sellOrders, | ||||||
|  |         LibSignature.Signature[] memory signatures, | ||||||
|  |         bytes[] memory callbackData, | ||||||
|  |         bool revertIfIncomplete | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         payable | ||||||
|  |         returns (bool[] memory successes) | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             sellOrders.length == signatures.length && | ||||||
|  |             sellOrders.length == callbackData.length, | ||||||
|  |             "ERC721OrdersFeature::batchBuyERC721s/ARRAY_LENGTH_MISMATCH" | ||||||
|  |         ); | ||||||
|  |         successes = new bool[](sellOrders.length); | ||||||
|  |  | ||||||
|  |         uint256 ethBalanceBefore = address(this).balance | ||||||
|  |             .safeSub(msg.value); | ||||||
|  |         if (revertIfIncomplete) { | ||||||
|  |             for (uint256 i = 0; i < sellOrders.length; i++) { | ||||||
|  |                 // Will revert if _buyERC721 reverts. | ||||||
|  |                 _buyERC721( | ||||||
|  |                     sellOrders[i], | ||||||
|  |                     signatures[i], | ||||||
|  |                     address(this).balance.safeSub(ethBalanceBefore), | ||||||
|  |                     callbackData[i] | ||||||
|  |                 ); | ||||||
|  |                 successes[i] = true; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             for (uint256 i = 0; i < sellOrders.length; i++) { | ||||||
|  |                 // Delegatecall `_buyERC721` to swallow reverts while | ||||||
|  |                 // preserving execution context. | ||||||
|  |                 // Note that `_buyERC721` is a public function but should _not_ | ||||||
|  |                 // be registered in the Exchange Proxy. | ||||||
|  |                 (successes[i], ) = _implementation.delegatecall( | ||||||
|  |                     abi.encodeWithSelector( | ||||||
|  |                         this._buyERC721.selector, | ||||||
|  |                         sellOrders[i], | ||||||
|  |                         signatures[i], | ||||||
|  |                         address(this).balance.safeSub(ethBalanceBefore), // Remaining ETH available | ||||||
|  |                         callbackData[i] | ||||||
|  |                     ) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Cannot use pre-existing ETH balance | ||||||
|  |         uint256 ethBalanceAfter = address(this).balance; | ||||||
|  |         if (ethBalanceAfter < ethBalanceBefore) { | ||||||
|  |             LibNFTOrdersRichErrors.OverspentEthError( | ||||||
|  |                 msg.value + (ethBalanceBefore - ethBalanceAfter), | ||||||
|  |                 msg.value | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Refund | ||||||
|  |         _transferEth(msg.sender, ethBalanceAfter - ethBalanceBefore); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Matches a pair of complementary orders that have | ||||||
|  |     ///      a non-negative spread. Each order is filled at | ||||||
|  |     ///      their respective price, and the matcher receives | ||||||
|  |     ///      a profit denominated in the ERC20 token. | ||||||
|  |     /// @param sellOrder Order selling an ERC721 asset. | ||||||
|  |     /// @param buyOrder Order buying an ERC721 asset. | ||||||
|  |     /// @param sellOrderSignature Signature for the sell order. | ||||||
|  |     /// @param buyOrderSignature Signature for the buy order. | ||||||
|  |     /// @return profit The amount of profit earned by the caller | ||||||
|  |     ///         of this function (denominated in the ERC20 token | ||||||
|  |     ///         of the matched orders). | ||||||
|  |     function matchERC721Orders( | ||||||
|  |         LibNFTOrder.ERC721Order memory sellOrder, | ||||||
|  |         LibNFTOrder.ERC721Order memory buyOrder, | ||||||
|  |         LibSignature.Signature memory sellOrderSignature, | ||||||
|  |         LibSignature.Signature memory buyOrderSignature | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         returns (uint256 profit) | ||||||
|  |     { | ||||||
|  |         // The ERC721 tokens must match | ||||||
|  |         if (sellOrder.erc721Token != buyOrder.erc721Token) { | ||||||
|  |             LibNFTOrdersRichErrors.ERC721TokenMismatchError( | ||||||
|  |                 address(sellOrder.erc721Token), | ||||||
|  |                 address(buyOrder.erc721Token) | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         LibNFTOrder.NFTOrder memory sellNFTOrder = sellOrder.asNFTOrder(); | ||||||
|  |         LibNFTOrder.NFTOrder memory buyNFTOrder = buyOrder.asNFTOrder(); | ||||||
|  |  | ||||||
|  |         { | ||||||
|  |             LibNFTOrder.OrderInfo memory sellOrderInfo = _getOrderInfo(sellNFTOrder); | ||||||
|  |             LibNFTOrder.OrderInfo memory buyOrderInfo = _getOrderInfo(buyNFTOrder); | ||||||
|  |  | ||||||
|  |             _validateSellOrder( | ||||||
|  |                 sellNFTOrder, | ||||||
|  |                 sellOrderSignature, | ||||||
|  |                 sellOrderInfo, | ||||||
|  |                 buyOrder.maker | ||||||
|  |             ); | ||||||
|  |             _validateBuyOrder( | ||||||
|  |                 buyNFTOrder, | ||||||
|  |                 buyOrderSignature, | ||||||
|  |                 buyOrderInfo, | ||||||
|  |                 sellOrder.maker, | ||||||
|  |                 sellOrder.erc721TokenId | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             // Mark both orders as filled. | ||||||
|  |             _updateOrderState(sellNFTOrder, sellOrderInfo.orderHash, 1); | ||||||
|  |             _updateOrderState(buyNFTOrder, buyOrderInfo.orderHash, 1); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // The buyer must be willing to pay at least the amount that the | ||||||
|  |         // seller is asking. | ||||||
|  |         if (buyOrder.erc20TokenAmount < sellOrder.erc20TokenAmount) { | ||||||
|  |             LibNFTOrdersRichErrors.NegativeSpreadError( | ||||||
|  |                 sellOrder.erc20TokenAmount, | ||||||
|  |                 buyOrder.erc20TokenAmount | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // The difference in ERC20 token amounts is the spread. | ||||||
|  |         uint256 spread = buyOrder.erc20TokenAmount - sellOrder.erc20TokenAmount; | ||||||
|  |  | ||||||
|  |         // Transfer the ERC721 asset from seller to buyer. | ||||||
|  |         _transferERC721AssetFrom( | ||||||
|  |             sellOrder.erc721Token, | ||||||
|  |             sellOrder.maker, | ||||||
|  |             buyOrder.maker, | ||||||
|  |             sellOrder.erc721TokenId | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // Handle the ERC20 side of the order: | ||||||
|  |         if ( | ||||||
|  |             address(sellOrder.erc20Token) == NATIVE_TOKEN_ADDRESS && | ||||||
|  |             buyOrder.erc20Token == WETH | ||||||
|  |         ) { | ||||||
|  |             // The sell order specifies ETH, while the buy order specifies WETH. | ||||||
|  |             // The orders are still compatible with one another, but we'll have | ||||||
|  |             // to unwrap the WETH on behalf of the buyer. | ||||||
|  |  | ||||||
|  |             // Step 1: Transfer WETH from the buyer to the EP. | ||||||
|  |             //         Note that we transfer `buyOrder.erc20TokenAmount`, which | ||||||
|  |             //         is the amount the buyer signaled they are willing to pay | ||||||
|  |             //         for the ERC721 asset, which may be more than the seller's | ||||||
|  |             //         ask. | ||||||
|  |             _transferERC20TokensFrom( | ||||||
|  |                 WETH, | ||||||
|  |                 buyOrder.maker, | ||||||
|  |                 address(this), | ||||||
|  |                 buyOrder.erc20TokenAmount | ||||||
|  |             ); | ||||||
|  |             // Step 2: Unwrap the WETH into ETH. We unwrap the entire | ||||||
|  |             //         `buyOrder.erc20TokenAmount`. | ||||||
|  |             //         The ETH will be used for three purposes: | ||||||
|  |             //         - To pay the seller | ||||||
|  |             //         - To pay fees for the sell order | ||||||
|  |             //         - Any remaining ETH will be sent to | ||||||
|  |             //           `msg.sender` as profit. | ||||||
|  |             WETH.withdraw(buyOrder.erc20TokenAmount); | ||||||
|  |  | ||||||
|  |             // Step 3: Pay the seller (in ETH). | ||||||
|  |             _transferEth(payable(sellOrder.maker), sellOrder.erc20TokenAmount); | ||||||
|  |  | ||||||
|  |             // Step 4: Pay fees for the buy order. Note that these are paid | ||||||
|  |             //         in _WETH_ by the _buyer_. By signing the buy order, the | ||||||
|  |             //         buyer signals that they are willing to spend a total | ||||||
|  |             //         of `erc20TokenAmount` _plus_ fees, all denominated in | ||||||
|  |             //         the `erc20Token`, which in this case is WETH. | ||||||
|  |             _payFees( | ||||||
|  |                 buyNFTOrder, | ||||||
|  |                 buyOrder.maker, // payer | ||||||
|  |                 1,              // fillAmount | ||||||
|  |                 1,              // orderAmount | ||||||
|  |                 false           // useNativeToken | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             // Step 5: Pay fees for the sell order. The `erc20Token` of the | ||||||
|  |             //         sell order is ETH, so the fees are paid out in ETH. | ||||||
|  |             //         There should be `spread` wei of ETH remaining in the | ||||||
|  |             //         EP at this point, which we will use ETH to pay the | ||||||
|  |             //         sell order fees. | ||||||
|  |             uint256 sellOrderFees = _payFees( | ||||||
|  |                 sellNFTOrder, | ||||||
|  |                 address(this), // payer | ||||||
|  |                 1,             // fillAmount | ||||||
|  |                 1,             // orderAmount | ||||||
|  |                 true           // useNativeToken | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             // Step 6: The spread must be enough to cover the sell order fees. | ||||||
|  |             //         If not, either `_payFees` will have reverted, or we | ||||||
|  |             //         have spent ETH that was in the EP before this | ||||||
|  |             //         `matchERC721Orders` call, which we disallow. | ||||||
|  |             if (spread < sellOrderFees) { | ||||||
|  |                 LibNFTOrdersRichErrors.SellOrderFeesExceedSpreadError( | ||||||
|  |                     sellOrderFees, | ||||||
|  |                     spread | ||||||
|  |                 ).rrevert(); | ||||||
|  |             } | ||||||
|  |             // Step 7: The spread less the sell order fees is the amount of ETH | ||||||
|  |             //         remaining in the EP that can be sent to `msg.sender` as | ||||||
|  |             //         the profit from matching these two orders. | ||||||
|  |             profit = spread - sellOrderFees; | ||||||
|  |             if (profit > 0) { | ||||||
|  |                 _transferEth(msg.sender, profit); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             // ERC20 tokens must match | ||||||
|  |             if (sellOrder.erc20Token != buyOrder.erc20Token) { | ||||||
|  |                 LibNFTOrdersRichErrors.ERC20TokenMismatchError( | ||||||
|  |                     address(sellOrder.erc20Token), | ||||||
|  |                     address(buyOrder.erc20Token) | ||||||
|  |                 ).rrevert(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Step 1: Transfer the ERC20 token from the buyer to the seller. | ||||||
|  |             //         Note that we transfer `sellOrder.erc20TokenAmount`, which | ||||||
|  |             //         is at most `buyOrder.erc20TokenAmount`. | ||||||
|  |             _transferERC20TokensFrom( | ||||||
|  |                 buyOrder.erc20Token, | ||||||
|  |                 buyOrder.maker, | ||||||
|  |                 sellOrder.maker, | ||||||
|  |                 sellOrder.erc20TokenAmount | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             // Step 2: Pay fees for the buy order. Note that these are paid | ||||||
|  |             //         by the buyer. By signing the buy order, the buyer signals | ||||||
|  |             //         that they are willing to spend a total of | ||||||
|  |             //         `buyOrder.erc20TokenAmount` _plus_ `buyOrder.fees`. | ||||||
|  |             _payFees( | ||||||
|  |                 buyNFTOrder, | ||||||
|  |                 buyOrder.maker, // payer | ||||||
|  |                 1,              // fillAmount | ||||||
|  |                 1,              // orderAmount | ||||||
|  |                 false           // useNativeToken | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             // Step 3: Pay fees for the sell order. These are paid by the buyer | ||||||
|  |             //         as well. After paying these fees, we may have taken more | ||||||
|  |             //         from the buyer than they agreed to in the buy order. If | ||||||
|  |             //         so, we revert in the following step. | ||||||
|  |             uint256 sellOrderFees = _payFees( | ||||||
|  |                 sellNFTOrder, | ||||||
|  |                 buyOrder.maker, // payer | ||||||
|  |                 1,              // fillAmount | ||||||
|  |                 1,              // orderAmount | ||||||
|  |                 false           // useNativeToken | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             // Step 4: The spread must be enough to cover the sell order fees. | ||||||
|  |             //         If not, `_payFees` will have taken more tokens from the | ||||||
|  |             //         buyer than they had agreed to in the buy order, in which | ||||||
|  |             //         case we revert here. | ||||||
|  |             if (spread < sellOrderFees) { | ||||||
|  |                 LibNFTOrdersRichErrors.SellOrderFeesExceedSpreadError( | ||||||
|  |                     sellOrderFees, | ||||||
|  |                     spread | ||||||
|  |                 ).rrevert(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Step 5: We calculate the profit as: | ||||||
|  |             //         profit = buyOrder.erc20TokenAmount - sellOrder.erc20TokenAmount - sellOrderFees | ||||||
|  |             //                = spread - sellOrderFees | ||||||
|  |             //         I.e. the buyer would've been willing to pay up to `profit` | ||||||
|  |             //         more to buy the asset, so instead that amount is sent to | ||||||
|  |             //         `msg.sender` as the profit from matching these two orders. | ||||||
|  |             profit = spread - sellOrderFees; | ||||||
|  |             if (profit > 0) { | ||||||
|  |                 _transferERC20TokensFrom( | ||||||
|  |                     buyOrder.erc20Token, | ||||||
|  |                     buyOrder.maker, | ||||||
|  |                     msg.sender, | ||||||
|  |                     profit | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit ERC721OrderFilled( | ||||||
|  |             sellOrder.direction, | ||||||
|  |             sellOrder.maker, | ||||||
|  |             buyOrder.maker, // taker | ||||||
|  |             sellOrder.nonce, | ||||||
|  |             sellOrder.erc20Token, | ||||||
|  |             sellOrder.erc20TokenAmount, | ||||||
|  |             sellOrder.erc721Token, | ||||||
|  |             sellOrder.erc721TokenId, | ||||||
|  |             msg.sender | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         emit ERC721OrderFilled( | ||||||
|  |             buyOrder.direction, | ||||||
|  |             buyOrder.maker, | ||||||
|  |             sellOrder.maker, // taker | ||||||
|  |             buyOrder.nonce, | ||||||
|  |             buyOrder.erc20Token, | ||||||
|  |             buyOrder.erc20TokenAmount, | ||||||
|  |             buyOrder.erc721Token, | ||||||
|  |             sellOrder.erc721TokenId, | ||||||
|  |             msg.sender | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Matches pairs of complementary orders that have | ||||||
|  |     ///      non-negative spreads. Each order is filled at | ||||||
|  |     ///      their respective price, and the matcher receives | ||||||
|  |     ///      a profit denominated in the ERC20 token. | ||||||
|  |     /// @param sellOrders Orders selling ERC721 assets. | ||||||
|  |     /// @param buyOrders Orders buying ERC721 assets. | ||||||
|  |     /// @param sellOrderSignatures Signatures for the sell orders. | ||||||
|  |     /// @param buyOrderSignatures Signatures for the buy orders. | ||||||
|  |     /// @return profits The amount of profit earned by the caller | ||||||
|  |     ///         of this function for each pair of matched orders | ||||||
|  |     ///         (denominated in the ERC20 token of the order pair). | ||||||
|  |     /// @return successes An array of booleans corresponding to | ||||||
|  |     ///         whether each pair of orders was successfully matched. | ||||||
|  |     function batchMatchERC721Orders( | ||||||
|  |         LibNFTOrder.ERC721Order[] memory sellOrders, | ||||||
|  |         LibNFTOrder.ERC721Order[] memory buyOrders, | ||||||
|  |         LibSignature.Signature[] memory sellOrderSignatures, | ||||||
|  |         LibSignature.Signature[] memory buyOrderSignatures | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         returns (uint256[] memory profits, bool[] memory successes) | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             sellOrders.length == buyOrders.length && | ||||||
|  |             sellOrderSignatures.length == buyOrderSignatures.length && | ||||||
|  |             sellOrders.length == sellOrderSignatures.length, | ||||||
|  |             "ERC721OrdersFeature::batchMatchERC721Orders/ARRAY_LENGTH_MISMATCH" | ||||||
|  |         ); | ||||||
|  |         profits = new uint256[](sellOrders.length); | ||||||
|  |         successes = new bool[](sellOrders.length); | ||||||
|  |  | ||||||
|  |         for (uint256 i = 0; i < sellOrders.length; i++) { | ||||||
|  |             bytes memory returnData; | ||||||
|  |             // Delegatecall `matchERC721Orders` to catch reverts while | ||||||
|  |             // preserving execution context. | ||||||
|  |             (successes[i], returnData) = _implementation.delegatecall( | ||||||
|  |                 abi.encodeWithSelector( | ||||||
|  |                     this.matchERC721Orders.selector, | ||||||
|  |                     sellOrders[i], | ||||||
|  |                     buyOrders[i], | ||||||
|  |                     sellOrderSignatures[i], | ||||||
|  |                     buyOrderSignatures[i] | ||||||
|  |                 ) | ||||||
|  |             ); | ||||||
|  |             if (successes[i]) { | ||||||
|  |                 // If the matching succeeded, record the profit. | ||||||
|  |                 (uint256 profit) = abi.decode(returnData, (uint256)); | ||||||
|  |                 profits[i] = profit; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Callback for the ERC721 `safeTransferFrom` function. | ||||||
|  |     ///      This callback can be used to sell an ERC721 asset if | ||||||
|  |     ///      a valid ERC721 order, signature and `unwrapNativeToken` | ||||||
|  |     ///      are encoded in `data`. This allows takers to sell their | ||||||
|  |     ///      ERC721 asset without first calling `setApprovalForAll`. | ||||||
|  |     /// @param operator The address which called `safeTransferFrom`. | ||||||
|  |     /// @param tokenId The ID of the asset being transferred. | ||||||
|  |     /// @param data Additional data with no specified format. If a | ||||||
|  |     ///        valid ERC721 order, signature and `unwrapNativeToken` | ||||||
|  |     ///        are encoded in `data`, this function will try to fill | ||||||
|  |     ///        the order using the received asset. | ||||||
|  |     /// @return success The selector of this function (0x150b7a02), | ||||||
|  |     ///         indicating that the callback succeeded. | ||||||
|  |     function onERC721Received( | ||||||
|  |         address operator, | ||||||
|  |         address /* from */, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         returns (bytes4 success) | ||||||
|  |     { | ||||||
|  |         // Decode the order, signature, and `unwrapNativeToken` from | ||||||
|  |         // `data`. If `data` does not encode such parameters, this | ||||||
|  |         // will throw. | ||||||
|  |         ( | ||||||
|  |             LibNFTOrder.ERC721Order memory buyOrder, | ||||||
|  |             LibSignature.Signature memory signature, | ||||||
|  |             bool unwrapNativeToken | ||||||
|  |         ) = abi.decode( | ||||||
|  |             data, | ||||||
|  |             (LibNFTOrder.ERC721Order, LibSignature.Signature, bool) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // `onERC721Received` is called by the ERC721 token contract. | ||||||
|  |         // Check that it matches the ERC721 token in the order. | ||||||
|  |         if (msg.sender != address(buyOrder.erc721Token)) { | ||||||
|  |             LibNFTOrdersRichErrors.ERC721TokenMismatchError( | ||||||
|  |                 msg.sender, | ||||||
|  |                 address(buyOrder.erc721Token) | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         _sellERC721( | ||||||
|  |             buyOrder, | ||||||
|  |             signature, | ||||||
|  |             tokenId, | ||||||
|  |             unwrapNativeToken, | ||||||
|  |             operator,       // taker | ||||||
|  |             address(this),  // owner (we hold the NFT currently) | ||||||
|  |             new bytes(0)    // No taker callback | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         return ERC721_RECEIVED_MAGIC_BYTES; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Approves an ERC721 order on-chain. After pre-signing | ||||||
|  |     ///      the order, the `PRESIGNED` signature type will become | ||||||
|  |     ///      valid for that order and signer. | ||||||
|  |     /// @param order An ERC721 order. | ||||||
|  |     function preSignERC721Order(LibNFTOrder.ERC721Order memory order) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             order.maker == msg.sender, | ||||||
|  |             "ERC721OrdersFeature::preSignERC721Order/ONLY_MAKER" | ||||||
|  |         ); | ||||||
|  |         bytes32 orderHash = getERC721OrderHash(order); | ||||||
|  |         LibERC721OrdersStorage.getStorage().preSigned[orderHash] = true; | ||||||
|  |  | ||||||
|  |         emit ERC721OrderPreSigned( | ||||||
|  |             order.direction, | ||||||
|  |             order.maker, | ||||||
|  |             order.taker, | ||||||
|  |             order.expiry, | ||||||
|  |             order.nonce, | ||||||
|  |             order.erc20Token, | ||||||
|  |             order.erc20TokenAmount, | ||||||
|  |             order.fees, | ||||||
|  |             order.erc721Token, | ||||||
|  |             order.erc721TokenId, | ||||||
|  |             order.erc721TokenProperties | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Core settlement logic for selling an ERC721 asset. | ||||||
|  |     // Used by `sellERC721` and `onERC721Received`. | ||||||
|  |     function _sellERC721( | ||||||
|  |         LibNFTOrder.ERC721Order memory buyOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         uint256 erc721TokenId, | ||||||
|  |         bool unwrapNativeToken, | ||||||
|  |         address taker, | ||||||
|  |         address currentNftOwner, | ||||||
|  |         bytes memory takerCallbackData | ||||||
|  |     ) | ||||||
|  |         private | ||||||
|  |     { | ||||||
|  |         _sellNFT( | ||||||
|  |             buyOrder.asNFTOrder(), | ||||||
|  |             signature, | ||||||
|  |             SellParams( | ||||||
|  |                 1, // sell amount | ||||||
|  |                 erc721TokenId, | ||||||
|  |                 unwrapNativeToken, | ||||||
|  |                 taker, | ||||||
|  |                 currentNftOwner, | ||||||
|  |                 takerCallbackData | ||||||
|  |             ) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         emit ERC721OrderFilled( | ||||||
|  |             buyOrder.direction, | ||||||
|  |             buyOrder.maker, | ||||||
|  |             taker, | ||||||
|  |             buyOrder.nonce, | ||||||
|  |             buyOrder.erc20Token, | ||||||
|  |             buyOrder.erc20TokenAmount, | ||||||
|  |             buyOrder.erc721Token, | ||||||
|  |             erc721TokenId, | ||||||
|  |             address(0) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Core settlement logic for buying an ERC721 asset. | ||||||
|  |     // Used by `buyERC721` and `batchBuyERC721s`. | ||||||
|  |     function _buyERC721( | ||||||
|  |         LibNFTOrder.ERC721Order memory sellOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         uint256 ethAvailable, | ||||||
|  |         bytes memory takerCallbackData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         payable | ||||||
|  |     { | ||||||
|  |         _buyNFT( | ||||||
|  |             sellOrder.asNFTOrder(), | ||||||
|  |             signature, | ||||||
|  |             BuyParams( | ||||||
|  |                 1, // buy amount | ||||||
|  |                 ethAvailable, | ||||||
|  |                 takerCallbackData | ||||||
|  |             ) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         emit ERC721OrderFilled( | ||||||
|  |             sellOrder.direction, | ||||||
|  |             sellOrder.maker, | ||||||
|  |             msg.sender, | ||||||
|  |             sellOrder.nonce, | ||||||
|  |             sellOrder.erc20Token, | ||||||
|  |             sellOrder.erc20TokenAmount, | ||||||
|  |             sellOrder.erc721Token, | ||||||
|  |             sellOrder.erc721TokenId, | ||||||
|  |             address(0) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// @dev Checks whether the given signature is valid for the | ||||||
|  |     ///      the given ERC721 order. Reverts if not. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @param signature The signature to validate. | ||||||
|  |     function validateERC721OrderSignature( | ||||||
|  |         LibNFTOrder.ERC721Order memory order, | ||||||
|  |         LibSignature.Signature memory signature | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         bytes32 orderHash = getERC721OrderHash(order); | ||||||
|  |         _validateOrderSignature(orderHash, signature, order.maker); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Validates that the given signature is valid for the | ||||||
|  |     ///      given maker and order hash. Reverts if the signature | ||||||
|  |     ///      is not valid. | ||||||
|  |     /// @param orderHash The hash of the order that was signed. | ||||||
|  |     /// @param signature The signature to check. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     function _validateOrderSignature( | ||||||
|  |         bytes32 orderHash, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         address maker | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         if (signature.signatureType == LibSignature.SignatureType.PRESIGNED) { | ||||||
|  |             // Check if order hash has been pre-signed by the maker. | ||||||
|  |             bool isPreSigned = LibERC721OrdersStorage.getStorage().preSigned[orderHash]; | ||||||
|  |             if (!isPreSigned) { | ||||||
|  |                 LibNFTOrdersRichErrors.InvalidSignerError(maker, address(0)).rrevert(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             address signer = LibSignature.getSignerOfHash(orderHash, signature); | ||||||
|  |             if (signer != maker) { | ||||||
|  |                 LibNFTOrdersRichErrors.InvalidSignerError(maker, signer).rrevert(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Transfers an NFT asset. | ||||||
|  |     /// @param token The address of the NFT contract. | ||||||
|  |     /// @param from The address currently holding the asset. | ||||||
|  |     /// @param to The address to transfer the asset to. | ||||||
|  |     /// @param tokenId The ID of the asset to transfer. | ||||||
|  |     /// @param amount The amount of the asset to transfer. Always | ||||||
|  |     ///        1 for ERC721 assets. | ||||||
|  |     function _transferNFTAssetFrom( | ||||||
|  |         address token, | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 amount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         assert(amount == 1); | ||||||
|  |         _transferERC721AssetFrom(IERC721Token(token), from, to, tokenId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Updates storage to indicate that the given order | ||||||
|  |     ///      has been filled by the given amount. | ||||||
|  |     /// @param order The order that has been filled. | ||||||
|  |     /// @param fillAmount The amount (denominated in the NFT asset) | ||||||
|  |     ///        that the order has been filled by. | ||||||
|  |     function _updateOrderState( | ||||||
|  |         LibNFTOrder.NFTOrder memory order, | ||||||
|  |         bytes32 /* orderHash */, | ||||||
|  |         uint128 fillAmount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |     { | ||||||
|  |         assert(fillAmount == 1); | ||||||
|  |         _setOrderStatusBit(order.maker, order.nonce); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _setOrderStatusBit(address maker, uint256 nonce) | ||||||
|  |         private | ||||||
|  |     { | ||||||
|  |         // The bitvector is indexed by the lower 8 bits of the nonce. | ||||||
|  |         uint256 flag = 1 << (nonce & 255); | ||||||
|  |         // Update order status bit vector to indicate that the given order | ||||||
|  |         // has been cancelled/filled by setting the designated bit to 1. | ||||||
|  |         LibERC721OrdersStorage.getStorage().orderStatusByMaker | ||||||
|  |             [maker][uint248(nonce >> 8)] |= flag; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev If the given order is buying an ERC721 asset, checks | ||||||
|  |     ///      whether or not the given token ID satisfies the required | ||||||
|  |     ///      properties specified in the order. If the order does not | ||||||
|  |     ///      specify any properties, this function instead checks | ||||||
|  |     ///      whether the given token ID matches the ID in the order. | ||||||
|  |     ///      Reverts if any checks fail, or if the order is selling | ||||||
|  |     ///      an ERC721 asset. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @param erc721TokenId The ID of the ERC721 asset. | ||||||
|  |     function validateERC721OrderProperties( | ||||||
|  |         LibNFTOrder.ERC721Order memory order, | ||||||
|  |         uint256 erc721TokenId | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         _validateOrderProperties( | ||||||
|  |             order.asNFTOrder(), | ||||||
|  |             erc721TokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the current status of an ERC721 order. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @return status The status of the order. | ||||||
|  |     function getERC721OrderStatus(LibNFTOrder.ERC721Order memory order) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderStatus status) | ||||||
|  |     { | ||||||
|  |         // Only buy orders with `erc721TokenId` == 0 can be property | ||||||
|  |         // orders. | ||||||
|  |         if (order.erc721TokenProperties.length > 0 && | ||||||
|  |                 (order.direction != LibNFTOrder.TradeDirection.BUY_NFT || | ||||||
|  |                  order.erc721TokenId != 0)) | ||||||
|  |         { | ||||||
|  |             return LibNFTOrder.OrderStatus.INVALID; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Buy orders cannot use ETH as the ERC20 token, since ETH cannot be | ||||||
|  |         // transferred from the buyer by a contract. | ||||||
|  |         if (order.direction == LibNFTOrder.TradeDirection.BUY_NFT && | ||||||
|  |             address(order.erc20Token) == NATIVE_TOKEN_ADDRESS) | ||||||
|  |         { | ||||||
|  |             return LibNFTOrder.OrderStatus.INVALID; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check for expiry. | ||||||
|  |         if (order.expiry <= block.timestamp) { | ||||||
|  |             return LibNFTOrder.OrderStatus.EXPIRED; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check `orderStatusByMaker` state variable to see if the order | ||||||
|  |         // has been cancelled or previously filled. | ||||||
|  |         LibERC721OrdersStorage.Storage storage stor = | ||||||
|  |             LibERC721OrdersStorage.getStorage(); | ||||||
|  |         // `orderStatusByMaker` is indexed by maker and nonce. | ||||||
|  |         uint256 orderStatusBitVector = | ||||||
|  |             stor.orderStatusByMaker[order.maker][uint248(order.nonce >> 8)]; | ||||||
|  |         // The bitvector is indexed by the lower 8 bits of the nonce. | ||||||
|  |         uint256 flag = 1 << (order.nonce & 255); | ||||||
|  |         // If the designated bit is set, the order has been cancelled or | ||||||
|  |         // previously filled, so it is now unfillable. | ||||||
|  |         if (orderStatusBitVector & flag != 0) { | ||||||
|  |             return LibNFTOrder.OrderStatus.UNFILLABLE; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Otherwise, the order is fillable. | ||||||
|  |         return LibNFTOrder.OrderStatus.FILLABLE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the order info for an NFT order. | ||||||
|  |     /// @param order The NFT order. | ||||||
|  |     /// @return orderInfo Info about the order. | ||||||
|  |     function _getOrderInfo(LibNFTOrder.NFTOrder memory order) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderInfo memory orderInfo) | ||||||
|  |     { | ||||||
|  |         LibNFTOrder.ERC721Order memory erc721Order = order.asERC721Order(); | ||||||
|  |         orderInfo.orderHash = getERC721OrderHash(erc721Order); | ||||||
|  |         orderInfo.status = getERC721OrderStatus(erc721Order); | ||||||
|  |         orderInfo.orderAmount = 1; | ||||||
|  |         orderInfo.remainingAmount = orderInfo.status == LibNFTOrder.OrderStatus.FILLABLE ? 1 : 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the EIP-712 hash of an ERC721 order. | ||||||
|  |     /// @param order The ERC721 order. | ||||||
|  |     /// @return orderHash The order hash. | ||||||
|  |     function getERC721OrderHash(LibNFTOrder.ERC721Order memory order) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (bytes32 orderHash) | ||||||
|  |     { | ||||||
|  |         return _getEIP712Hash(LibNFTOrder.getERC721OrderStructHash(order)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the order status bit vector for the given | ||||||
|  |     ///      maker address and nonce range. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     /// @param nonceRange Order status bit vectors are indexed | ||||||
|  |     ///        by maker address and the upper 248 bits of the | ||||||
|  |     ///        order nonce. We define `nonceRange` to be these | ||||||
|  |     ///        248 bits. | ||||||
|  |     /// @return bitVector The order status bit vector for the | ||||||
|  |     ///         given maker and nonce range. | ||||||
|  |     function getERC721OrderStatusBitVector(address maker, uint248 nonceRange) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         view | ||||||
|  |         returns (uint256 bitVector) | ||||||
|  |     { | ||||||
|  |         LibERC721OrdersStorage.Storage storage stor = | ||||||
|  |             LibERC721OrdersStorage.getStorage(); | ||||||
|  |         return stor.orderStatusByMaker[maker][nonceRange]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,615 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  | import "../../errors/LibNFTOrdersRichErrors.sol"; | ||||||
|  | import "../../fixins/FixinCommon.sol"; | ||||||
|  | import "../../fixins/FixinEIP712.sol"; | ||||||
|  | import "../../fixins/FixinTokenSpender.sol"; | ||||||
|  | import "../../migrations/LibMigrate.sol"; | ||||||
|  | import "../../vendor/IFeeRecipient.sol"; | ||||||
|  | import "../../vendor/ITakerCallback.sol"; | ||||||
|  | import "../libs/LibSignature.sol"; | ||||||
|  | import "../libs/LibNFTOrder.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Abstract base contract inherited by ERC721OrdersFeature and NFTOrders | ||||||
|  | abstract contract NFTOrders is | ||||||
|  |     FixinCommon, | ||||||
|  |     FixinEIP712, | ||||||
|  |     FixinTokenSpender | ||||||
|  | { | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |  | ||||||
|  |     /// @dev Native token pseudo-address. | ||||||
|  |     address constant internal NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | ||||||
|  |     /// @dev The WETH token contract. | ||||||
|  |     IEtherTokenV06 internal immutable WETH; | ||||||
|  |  | ||||||
|  |     /// @dev The magic return value indicating the success of a `receiveZeroExFeeCallback`. | ||||||
|  |     bytes4 private constant FEE_CALLBACK_MAGIC_BYTES = IFeeRecipient.receiveZeroExFeeCallback.selector; | ||||||
|  |     /// @dev The magic return value indicating the success of a `zeroExTakerCallback`. | ||||||
|  |     bytes4 private constant TAKER_CALLBACK_MAGIC_BYTES = ITakerCallback.zeroExTakerCallback.selector; | ||||||
|  |  | ||||||
|  |     constructor(address zeroExAddress, IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         FixinEIP712(zeroExAddress) | ||||||
|  |     { | ||||||
|  |         WETH = weth; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct SellParams { | ||||||
|  |         uint128 sellAmount; | ||||||
|  |         uint256 tokenId; | ||||||
|  |         bool unwrapNativeToken; | ||||||
|  |         address taker; | ||||||
|  |         address currentNftOwner; | ||||||
|  |         bytes takerCallbackData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct BuyParams { | ||||||
|  |         uint128 buyAmount; | ||||||
|  |         uint256 ethAvailable; | ||||||
|  |         bytes takerCallbackData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Core settlement logic for selling an NFT asset. | ||||||
|  |     function _sellNFT( | ||||||
|  |         LibNFTOrder.NFTOrder memory buyOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         SellParams memory params | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         returns (uint256 erc20FillAmount) | ||||||
|  |     { | ||||||
|  |         LibNFTOrder.OrderInfo memory orderInfo = _getOrderInfo(buyOrder); | ||||||
|  |         // Check that the order can be filled. | ||||||
|  |         _validateBuyOrder( | ||||||
|  |             buyOrder, | ||||||
|  |             signature, | ||||||
|  |             orderInfo, | ||||||
|  |             params.taker, | ||||||
|  |             params.tokenId | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         if (params.sellAmount > orderInfo.remainingAmount) { | ||||||
|  |             LibNFTOrdersRichErrors.ExceedsRemainingOrderAmount( | ||||||
|  |                 orderInfo.remainingAmount, | ||||||
|  |                 params.sellAmount | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         _updateOrderState(buyOrder, orderInfo.orderHash, params.sellAmount); | ||||||
|  |  | ||||||
|  |         if (params.sellAmount == orderInfo.orderAmount) { | ||||||
|  |             erc20FillAmount = buyOrder.erc20TokenAmount; | ||||||
|  |         } else { | ||||||
|  |             // Rounding favors the order maker. | ||||||
|  |             erc20FillAmount = LibMathV06.getPartialAmountFloor( | ||||||
|  |                 params.sellAmount, | ||||||
|  |                 orderInfo.orderAmount, | ||||||
|  |                 buyOrder.erc20TokenAmount | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (params.unwrapNativeToken) { | ||||||
|  |             // The ERC20 token must be WETH for it to be unwrapped. | ||||||
|  |             if (buyOrder.erc20Token != WETH) { | ||||||
|  |                 LibNFTOrdersRichErrors.ERC20TokenMismatchError( | ||||||
|  |                     address(buyOrder.erc20Token), | ||||||
|  |                     address(WETH) | ||||||
|  |                 ).rrevert(); | ||||||
|  |             } | ||||||
|  |             // Transfer the WETH from the maker to the Exchange Proxy | ||||||
|  |             // so we can unwrap it before sending it to the seller. | ||||||
|  |             // TODO: Probably safe to just use WETH.transferFrom for some | ||||||
|  |             //       small gas savings | ||||||
|  |             _transferERC20TokensFrom( | ||||||
|  |                 WETH, | ||||||
|  |                 buyOrder.maker, | ||||||
|  |                 address(this), | ||||||
|  |                 erc20FillAmount | ||||||
|  |             ); | ||||||
|  |             // Unwrap WETH into ETH. | ||||||
|  |             WETH.withdraw(erc20FillAmount); | ||||||
|  |             // Send ETH to the seller. | ||||||
|  |             _transferEth(payable(params.taker), erc20FillAmount); | ||||||
|  |         } else { | ||||||
|  |             // Transfer the ERC20 token from the buyer to the seller. | ||||||
|  |             _transferERC20TokensFrom( | ||||||
|  |                 buyOrder.erc20Token, | ||||||
|  |                 buyOrder.maker, | ||||||
|  |                 params.taker, | ||||||
|  |                 erc20FillAmount | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (params.takerCallbackData.length > 0) { | ||||||
|  |             require( | ||||||
|  |                 params.taker != address(this), | ||||||
|  |                 "NFTOrders::_sellNFT/CANNOT_CALLBACK_SELF" | ||||||
|  |             ); | ||||||
|  |             // Invoke the callback | ||||||
|  |             bytes4 callbackResult = ITakerCallback(params.taker) | ||||||
|  |                 .zeroExTakerCallback(orderInfo.orderHash, params.takerCallbackData); | ||||||
|  |             // Check for the magic success bytes | ||||||
|  |             require( | ||||||
|  |                 callbackResult == TAKER_CALLBACK_MAGIC_BYTES, | ||||||
|  |                 "NFTOrders::_sellNFT/CALLBACK_FAILED" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Transfer the NFT asset to the buyer. | ||||||
|  |         // If this function is called from the | ||||||
|  |         // `onNFTReceived` callback the Exchange Proxy | ||||||
|  |         // holds the asset. Otherwise, transfer it from | ||||||
|  |         // the seller. | ||||||
|  |         _transferNFTAssetFrom( | ||||||
|  |             buyOrder.nft, | ||||||
|  |             params.currentNftOwner, | ||||||
|  |             buyOrder.maker, | ||||||
|  |             params.tokenId, | ||||||
|  |             params.sellAmount | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // The buyer pays the order fees. | ||||||
|  |         _payFees( | ||||||
|  |             buyOrder, | ||||||
|  |             buyOrder.maker, | ||||||
|  |             params.sellAmount, | ||||||
|  |             orderInfo.orderAmount, | ||||||
|  |             false | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Core settlement logic for buying an NFT asset. | ||||||
|  |     function _buyNFT( | ||||||
|  |         LibNFTOrder.NFTOrder memory sellOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         BuyParams memory params | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         returns (uint256 erc20FillAmount) | ||||||
|  |     { | ||||||
|  |         LibNFTOrder.OrderInfo memory orderInfo = _getOrderInfo(sellOrder); | ||||||
|  |         // Check that the order can be filled. | ||||||
|  |         _validateSellOrder( | ||||||
|  |             sellOrder, | ||||||
|  |             signature, | ||||||
|  |             orderInfo, | ||||||
|  |             msg.sender | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         if (params.buyAmount > orderInfo.remainingAmount) { | ||||||
|  |             LibNFTOrdersRichErrors.ExceedsRemainingOrderAmount( | ||||||
|  |                 orderInfo.remainingAmount, | ||||||
|  |                 params.buyAmount | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         _updateOrderState(sellOrder, orderInfo.orderHash, params.buyAmount); | ||||||
|  |  | ||||||
|  |         if (params.buyAmount == orderInfo.orderAmount) { | ||||||
|  |             erc20FillAmount = sellOrder.erc20TokenAmount; | ||||||
|  |         } else { | ||||||
|  |             // Rounding favors the order maker. | ||||||
|  |             erc20FillAmount = LibMathV06.getPartialAmountCeil( | ||||||
|  |                 params.buyAmount, | ||||||
|  |                 orderInfo.orderAmount, | ||||||
|  |                 sellOrder.erc20TokenAmount | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Transfer the NFT asset to the buyer (`msg.sender`). | ||||||
|  |         _transferNFTAssetFrom( | ||||||
|  |             sellOrder.nft, | ||||||
|  |             sellOrder.maker, | ||||||
|  |             msg.sender, | ||||||
|  |             sellOrder.nftId, | ||||||
|  |             params.buyAmount | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         uint256 ethAvailable = params.ethAvailable; | ||||||
|  |         if (params.takerCallbackData.length > 0) { | ||||||
|  |             require( | ||||||
|  |                 msg.sender != address(this), | ||||||
|  |                 "NFTOrders::_buyNFT/CANNOT_CALLBACK_SELF" | ||||||
|  |             ); | ||||||
|  |             uint256 ethBalanceBeforeCallback = address(this).balance; | ||||||
|  |             // Invoke the callback | ||||||
|  |             bytes4 callbackResult = ITakerCallback(msg.sender) | ||||||
|  |                 .zeroExTakerCallback(orderInfo.orderHash, params.takerCallbackData); | ||||||
|  |             // Update `ethAvailable` with amount acquired during | ||||||
|  |             // the callback | ||||||
|  |             ethAvailable = ethAvailable.safeAdd( | ||||||
|  |                 address(this).balance.safeSub(ethBalanceBeforeCallback) | ||||||
|  |             ); | ||||||
|  |             // Check for the magic success bytes | ||||||
|  |             require( | ||||||
|  |                 callbackResult == TAKER_CALLBACK_MAGIC_BYTES, | ||||||
|  |                 "NFTOrders::_buyNFT/CALLBACK_FAILED" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (address(sellOrder.erc20Token) == NATIVE_TOKEN_ADDRESS) { | ||||||
|  |             // Transfer ETH to the seller. | ||||||
|  |             _transferEth(payable(sellOrder.maker), erc20FillAmount); | ||||||
|  |             // Fees are paid from the EP's current balance of ETH. | ||||||
|  |             _payEthFees( | ||||||
|  |                 sellOrder, | ||||||
|  |                 params.buyAmount, | ||||||
|  |                 orderInfo.orderAmount, | ||||||
|  |                 erc20FillAmount, | ||||||
|  |                 ethAvailable | ||||||
|  |             ); | ||||||
|  |         } else if (sellOrder.erc20Token == WETH) { | ||||||
|  |             // If there is enough ETH available, fill the WETH order | ||||||
|  |             // (including fees) using that ETH. | ||||||
|  |             // Otherwise, transfer WETH from the taker. | ||||||
|  |             if (ethAvailable >= erc20FillAmount) { | ||||||
|  |                 // Wrap ETH. | ||||||
|  |                 WETH.deposit{value: erc20FillAmount}(); | ||||||
|  |                 // TODO: Probably safe to just use WETH.transfer for some | ||||||
|  |                 //       small gas savings | ||||||
|  |                 // Transfer WETH to the seller. | ||||||
|  |                 _transferERC20Tokens( | ||||||
|  |                     WETH, | ||||||
|  |                     sellOrder.maker, | ||||||
|  |                     erc20FillAmount | ||||||
|  |                 ); | ||||||
|  |                 // Fees are paid from the EP's current balance of ETH. | ||||||
|  |                 _payEthFees( | ||||||
|  |                     sellOrder, | ||||||
|  |                     params.buyAmount, | ||||||
|  |                     orderInfo.orderAmount, | ||||||
|  |                     erc20FillAmount, | ||||||
|  |                     ethAvailable | ||||||
|  |                 ); | ||||||
|  |             } else { | ||||||
|  |                 // Transfer WETH from the buyer to the seller. | ||||||
|  |                 _transferERC20TokensFrom( | ||||||
|  |                     sellOrder.erc20Token, | ||||||
|  |                     msg.sender, | ||||||
|  |                     sellOrder.maker, | ||||||
|  |                     erc20FillAmount | ||||||
|  |                 ); | ||||||
|  |                 // The buyer pays fees using WETH. | ||||||
|  |                 _payFees( | ||||||
|  |                     sellOrder, | ||||||
|  |                     msg.sender, | ||||||
|  |                     params.buyAmount, | ||||||
|  |                     orderInfo.orderAmount, | ||||||
|  |                     false | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             // Transfer ERC20 token from the buyer to the seller. | ||||||
|  |             _transferERC20TokensFrom( | ||||||
|  |                 sellOrder.erc20Token, | ||||||
|  |                 msg.sender, | ||||||
|  |                 sellOrder.maker, | ||||||
|  |                 erc20FillAmount | ||||||
|  |             ); | ||||||
|  |             // The buyer pays fees. | ||||||
|  |             _payFees( | ||||||
|  |                 sellOrder, | ||||||
|  |                 msg.sender, | ||||||
|  |                 params.buyAmount, | ||||||
|  |                 orderInfo.orderAmount, | ||||||
|  |                 false | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _validateSellOrder( | ||||||
|  |         LibNFTOrder.NFTOrder memory sellOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         LibNFTOrder.OrderInfo memory orderInfo, | ||||||
|  |         address taker | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         // Order must be selling the NFT asset. | ||||||
|  |         require( | ||||||
|  |             sellOrder.direction == LibNFTOrder.TradeDirection.SELL_NFT, | ||||||
|  |             "NFTOrders::_validateSellOrder/WRONG_TRADE_DIRECTION" | ||||||
|  |         ); | ||||||
|  |         // Taker must match the order taker, if one is specified. | ||||||
|  |         if (sellOrder.taker != address(0) && sellOrder.taker != taker) { | ||||||
|  |             LibNFTOrdersRichErrors.OnlyTakerError(taker, sellOrder.taker).rrevert(); | ||||||
|  |         } | ||||||
|  |         // Check that the order is valid and has not expired, been cancelled, | ||||||
|  |         // or been filled. | ||||||
|  |         if (orderInfo.status != LibNFTOrder.OrderStatus.FILLABLE) { | ||||||
|  |             LibNFTOrdersRichErrors.OrderNotFillableError( | ||||||
|  |                 sellOrder.maker, | ||||||
|  |                 sellOrder.nonce, | ||||||
|  |                 uint8(orderInfo.status) | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check the signature. | ||||||
|  |         _validateOrderSignature(orderInfo.orderHash, signature, sellOrder.maker); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _validateBuyOrder( | ||||||
|  |         LibNFTOrder.NFTOrder memory buyOrder, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         LibNFTOrder.OrderInfo memory orderInfo, | ||||||
|  |         address taker, | ||||||
|  |         uint256 tokenId | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         // Order must be buying the NFT asset. | ||||||
|  |         require( | ||||||
|  |             buyOrder.direction == LibNFTOrder.TradeDirection.BUY_NFT, | ||||||
|  |             "NFTOrders::_validateBuyOrder/WRONG_TRADE_DIRECTION" | ||||||
|  |         ); | ||||||
|  |         // The ERC20 token cannot be ETH. | ||||||
|  |         require( | ||||||
|  |             address(buyOrder.erc20Token) != NATIVE_TOKEN_ADDRESS, | ||||||
|  |             "NFTOrders::_validateBuyOrder/NATIVE_TOKEN_NOT_ALLOWED" | ||||||
|  |         ); | ||||||
|  |         // Taker must match the order taker, if one is specified. | ||||||
|  |         if (buyOrder.taker != address(0) && buyOrder.taker != taker) { | ||||||
|  |             LibNFTOrdersRichErrors.OnlyTakerError(taker, buyOrder.taker).rrevert(); | ||||||
|  |         } | ||||||
|  |         // Check that the order is valid and has not expired, been cancelled, | ||||||
|  |         // or been filled. | ||||||
|  |         if (orderInfo.status != LibNFTOrder.OrderStatus.FILLABLE) { | ||||||
|  |             LibNFTOrdersRichErrors.OrderNotFillableError( | ||||||
|  |                 buyOrder.maker, | ||||||
|  |                 buyOrder.nonce, | ||||||
|  |                 uint8(orderInfo.status) | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |         // Check that the asset with the given token ID satisfies the properties | ||||||
|  |         // specified by the order. | ||||||
|  |         _validateOrderProperties(buyOrder, tokenId); | ||||||
|  |         // Check the signature. | ||||||
|  |         _validateOrderSignature(orderInfo.orderHash, signature, buyOrder.maker); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _payEthFees( | ||||||
|  |         LibNFTOrder.NFTOrder memory order, | ||||||
|  |         uint128 fillAmount, | ||||||
|  |         uint128 orderAmount, | ||||||
|  |         uint256 ethSpent, | ||||||
|  |         uint256 ethAvailable | ||||||
|  |     ) | ||||||
|  |         private | ||||||
|  |     { | ||||||
|  |         // Pay fees using ETH. | ||||||
|  |         uint256 ethFees = _payFees( | ||||||
|  |             order, | ||||||
|  |             address(this), | ||||||
|  |             fillAmount, | ||||||
|  |             orderAmount, | ||||||
|  |             true | ||||||
|  |         ); | ||||||
|  |         // Update amount of ETH spent. | ||||||
|  |         ethSpent = ethSpent.safeAdd(ethFees); | ||||||
|  |         if (ethSpent > ethAvailable) { | ||||||
|  |             LibNFTOrdersRichErrors.OverspentEthError( | ||||||
|  |                 ethSpent, | ||||||
|  |                 ethAvailable | ||||||
|  |             ).rrevert(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _payFees( | ||||||
|  |         LibNFTOrder.NFTOrder memory order, | ||||||
|  |         address payer, | ||||||
|  |         uint128 fillAmount, | ||||||
|  |         uint128 orderAmount, | ||||||
|  |         bool useNativeToken | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         returns (uint256 totalFeesPaid) | ||||||
|  |     { | ||||||
|  |         // Make assertions about ETH case | ||||||
|  |         if (useNativeToken) { | ||||||
|  |             assert(payer == address(this)); | ||||||
|  |             assert( | ||||||
|  |                 order.erc20Token == WETH || | ||||||
|  |                 address(order.erc20Token) == NATIVE_TOKEN_ADDRESS | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         for (uint256 i = 0; i < order.fees.length; i++) { | ||||||
|  |             LibNFTOrder.Fee memory fee = order.fees[i]; | ||||||
|  |  | ||||||
|  |             require( | ||||||
|  |                 fee.recipient != address(this), | ||||||
|  |                 "NFTOrders::_payFees/RECIPIENT_CANNOT_BE_EXCHANGE_PROXY" | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |             uint256 feeFillAmount; | ||||||
|  |             if (fillAmount == orderAmount) { | ||||||
|  |                 feeFillAmount = fee.amount; | ||||||
|  |             } else { | ||||||
|  |                 // Round against the fee recipient | ||||||
|  |                 feeFillAmount = LibMathV06.getPartialAmountFloor( | ||||||
|  |                     fillAmount, | ||||||
|  |                     orderAmount, | ||||||
|  |                     fee.amount | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             if (feeFillAmount == 0) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (useNativeToken) { | ||||||
|  |                 // Transfer ETH to the fee recipient. | ||||||
|  |                 _transferEth(payable(fee.recipient), feeFillAmount); | ||||||
|  |             } else { | ||||||
|  |                 // Transfer ERC20 token from payer to recipient. | ||||||
|  |                 _transferERC20TokensFrom( | ||||||
|  |                     order.erc20Token, | ||||||
|  |                     payer, | ||||||
|  |                     fee.recipient, | ||||||
|  |                     feeFillAmount | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             // Note that the fee callback is _not_ called if zero | ||||||
|  |             // `feeData` is provided. If `feeData` is provided, we assume | ||||||
|  |             // the fee recipient is a contract that implements the | ||||||
|  |             // `IFeeRecipient` interface. | ||||||
|  |             if (fee.feeData.length > 0) { | ||||||
|  |                 // Invoke the callback | ||||||
|  |                 bytes4 callbackResult = IFeeRecipient(fee.recipient).receiveZeroExFeeCallback( | ||||||
|  |                     useNativeToken ? NATIVE_TOKEN_ADDRESS : address(order.erc20Token), | ||||||
|  |                     feeFillAmount, | ||||||
|  |                     fee.feeData | ||||||
|  |                 ); | ||||||
|  |                 // Check for the magic success bytes | ||||||
|  |                 require( | ||||||
|  |                     callbackResult == FEE_CALLBACK_MAGIC_BYTES, | ||||||
|  |                     "NFTOrders::_payFees/CALLBACK_FAILED" | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |             // Sum the fees paid | ||||||
|  |             totalFeesPaid = totalFeesPaid.safeAdd(feeFillAmount); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev If the given order is buying an NFT asset, checks | ||||||
|  |     ///      whether or not the given token ID satisfies the required | ||||||
|  |     ///      properties specified in the order. If the order does not | ||||||
|  |     ///      specify any properties, this function instead checks | ||||||
|  |     ///      whether the given token ID matches the ID in the order. | ||||||
|  |     ///      Reverts if any checks fail, or if the order is selling | ||||||
|  |     ///      an NFT asset. | ||||||
|  |     /// @param order The NFT order. | ||||||
|  |     /// @param tokenId The ID of the NFT asset. | ||||||
|  |     function _validateOrderProperties( | ||||||
|  |         LibNFTOrder.NFTOrder memory order, | ||||||
|  |         uint256 tokenId | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         view | ||||||
|  |     { | ||||||
|  |         // Order must be buying an NFT asset to have properties. | ||||||
|  |         require( | ||||||
|  |             order.direction == LibNFTOrder.TradeDirection.BUY_NFT, | ||||||
|  |             "NFTOrders::_validateOrderProperties/WRONG_TRADE_DIRECTION" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // If no properties are specified, check that the given | ||||||
|  |         // `tokenId` matches the one specified in the order. | ||||||
|  |         if (order.nftProperties.length == 0) { | ||||||
|  |             if (tokenId != order.nftId) { | ||||||
|  |                 LibNFTOrdersRichErrors.TokenIdMismatchError( | ||||||
|  |                     tokenId, | ||||||
|  |                     order.nftId | ||||||
|  |                 ).rrevert(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             // Validate each property | ||||||
|  |             for (uint256 i = 0; i < order.nftProperties.length; i++) { | ||||||
|  |                 LibNFTOrder.Property memory property = order.nftProperties[i]; | ||||||
|  |                 // `address(0)` is interpreted as a no-op. Any token ID | ||||||
|  |                 // will satisfy a property with `propertyValidator == address(0)`. | ||||||
|  |                 if (address(property.propertyValidator) == address(0)) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 // Call the property validator and throw a descriptive error | ||||||
|  |                 // if the call reverts. | ||||||
|  |                 try property.propertyValidator.validateProperty( | ||||||
|  |                     order.nft, | ||||||
|  |                     tokenId, | ||||||
|  |                     property.propertyData | ||||||
|  |                 ) {} catch (bytes memory errorData) { | ||||||
|  |                     LibNFTOrdersRichErrors.PropertyValidationFailedError( | ||||||
|  |                         address(property.propertyValidator), | ||||||
|  |                         order.nft, | ||||||
|  |                         tokenId, | ||||||
|  |                         property.propertyData, | ||||||
|  |                         errorData | ||||||
|  |                     ).rrevert(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Validates that the given signature is valid for the | ||||||
|  |     ///      given maker and order hash. Reverts if the signature | ||||||
|  |     ///      is not valid. | ||||||
|  |     /// @param orderHash The hash of the order that was signed. | ||||||
|  |     /// @param signature The signature to check. | ||||||
|  |     /// @param maker The maker of the order. | ||||||
|  |     function _validateOrderSignature( | ||||||
|  |         bytes32 orderHash, | ||||||
|  |         LibSignature.Signature memory signature, | ||||||
|  |         address maker | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         virtual | ||||||
|  |         view; | ||||||
|  |  | ||||||
|  |     /// @dev Transfers an NFT asset. | ||||||
|  |     /// @param token The address of the NFT contract. | ||||||
|  |     /// @param from The address currently holding the asset. | ||||||
|  |     /// @param to The address to transfer the asset to. | ||||||
|  |     /// @param tokenId The ID of the asset to transfer. | ||||||
|  |     /// @param amount The amount of the asset to transfer. Always | ||||||
|  |     ///        1 for ERC721 assets. | ||||||
|  |     function _transferNFTAssetFrom( | ||||||
|  |         address token, | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 amount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         virtual; | ||||||
|  |  | ||||||
|  |     /// @dev Updates storage to indicate that the given order | ||||||
|  |     ///      has been filled by the given amount. | ||||||
|  |     /// @param order The order that has been filled. | ||||||
|  |     /// @param orderHash The hash of `order`. | ||||||
|  |     /// @param fillAmount The amount (denominated in the NFT asset) | ||||||
|  |     ///        that the order has been filled by. | ||||||
|  |     function _updateOrderState( | ||||||
|  |         LibNFTOrder.NFTOrder memory order, | ||||||
|  |         bytes32 orderHash, | ||||||
|  |         uint128 fillAmount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         virtual; | ||||||
|  |  | ||||||
|  |     /// @dev Get the order info for an NFT order. | ||||||
|  |     /// @param order The NFT order. | ||||||
|  |     /// @return orderInfo Info about the order. | ||||||
|  |     function _getOrderInfo(LibNFTOrder.NFTOrder memory order) | ||||||
|  |         internal | ||||||
|  |         virtual | ||||||
|  |         view | ||||||
|  |         returns (LibNFTOrder.OrderInfo memory orderInfo); | ||||||
|  | } | ||||||
| @@ -0,0 +1,79 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  | import "../vendor/IERC1155Token.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Helpers for moving ERC1155 assets around. | ||||||
|  | abstract contract FixinERC1155Spender { | ||||||
|  |  | ||||||
|  |     // Mask of the lower 20 bytes of a bytes32. | ||||||
|  |     uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff; | ||||||
|  |  | ||||||
|  |     /// @dev Transfers an ERC1155 asset from `owner` to `to`. | ||||||
|  |     /// @param token The address of the ERC1155 token contract. | ||||||
|  |     /// @param owner The owner of the asset. | ||||||
|  |     /// @param to The recipient of the asset. | ||||||
|  |     /// @param tokenId The token ID of the asset to transfer. | ||||||
|  |     /// @param amount The amount of the asset to transfer. | ||||||
|  |     function _transferERC1155AssetFrom( | ||||||
|  |         IERC1155Token token, | ||||||
|  |         address owner, | ||||||
|  |         address to, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         uint256 amount | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |     { | ||||||
|  |         require(address(token) != address(this), "FixinERC1155Spender/CANNOT_INVOKE_SELF"); | ||||||
|  |  | ||||||
|  |         assembly { | ||||||
|  |             let ptr := mload(0x40) // free memory pointer | ||||||
|  |  | ||||||
|  |             // selector for safeTransferFrom(address,address,uint256,uint256,bytes) | ||||||
|  |             mstore(ptr, 0xf242432a00000000000000000000000000000000000000000000000000000000) | ||||||
|  |             mstore(add(ptr, 0x04), and(owner, ADDRESS_MASK)) | ||||||
|  |             mstore(add(ptr, 0x24), and(to, ADDRESS_MASK)) | ||||||
|  |             mstore(add(ptr, 0x44), tokenId) | ||||||
|  |             mstore(add(ptr, 0x64), amount) | ||||||
|  |             mstore(add(ptr, 0x84), 0xa0) | ||||||
|  |             mstore(add(ptr, 0xa4), 0) | ||||||
|  |  | ||||||
|  |             let success := call( | ||||||
|  |                 gas(), | ||||||
|  |                 and(token, ADDRESS_MASK), | ||||||
|  |                 0, | ||||||
|  |                 ptr, | ||||||
|  |                 0xc4, | ||||||
|  |                 0, | ||||||
|  |                 0 | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |             if iszero(success) { | ||||||
|  |                 let rdsize := returndatasize() | ||||||
|  |                 returndatacopy(ptr, 0, rdsize) | ||||||
|  |                 revert(ptr, rdsize) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,74 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  | import "../vendor/IERC721Token.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Helpers for moving ERC721 assets around. | ||||||
|  | abstract contract FixinERC721Spender { | ||||||
|  |  | ||||||
|  |     // Mask of the lower 20 bytes of a bytes32. | ||||||
|  |     uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff; | ||||||
|  |  | ||||||
|  |     /// @dev Transfers an ERC721 asset from `owner` to `to`. | ||||||
|  |     /// @param token The address of the ERC721 token contract. | ||||||
|  |     /// @param owner The owner of the asset. | ||||||
|  |     /// @param to The recipient of the asset. | ||||||
|  |     /// @param tokenId The token ID of the asset to transfer. | ||||||
|  |     function _transferERC721AssetFrom( | ||||||
|  |         IERC721Token token, | ||||||
|  |         address owner, | ||||||
|  |         address to, | ||||||
|  |         uint256 tokenId | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |     { | ||||||
|  |         require(address(token) != address(this), "FixinERC721Spender/CANNOT_INVOKE_SELF"); | ||||||
|  |  | ||||||
|  |         assembly { | ||||||
|  |             let ptr := mload(0x40) // free memory pointer | ||||||
|  |  | ||||||
|  |             // selector for transferFrom(address,address,uint256) | ||||||
|  |             mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000) | ||||||
|  |             mstore(add(ptr, 0x04), and(owner, ADDRESS_MASK)) | ||||||
|  |             mstore(add(ptr, 0x24), and(to, ADDRESS_MASK)) | ||||||
|  |             mstore(add(ptr, 0x44), tokenId) | ||||||
|  |  | ||||||
|  |             let success := call( | ||||||
|  |                 gas(), | ||||||
|  |                 and(token, ADDRESS_MASK), | ||||||
|  |                 0, | ||||||
|  |                 ptr, | ||||||
|  |                 0x64, | ||||||
|  |                 0, | ||||||
|  |                 0 | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |             if iszero(success) { | ||||||
|  |                 let rdsize := returndatasize() | ||||||
|  |                 returndatacopy(ptr, 0, rdsize) | ||||||
|  |                 revert(ptr, rdsize) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -20,7 +20,7 @@ | |||||||
| pragma solidity ^0.6.5; | pragma solidity ^0.6.5; | ||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
| import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -141,6 +141,20 @@ abstract contract FixinTokenSpender { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// @dev Transfers some amount of ETH to the given recipient and | ||||||
|  |     ///      reverts if the transfer fails. | ||||||
|  |     /// @param recipient The recipient of the ETH. | ||||||
|  |     /// @param amount The amount of ETH to transfer. | ||||||
|  |     function _transferEth(address payable recipient, uint256 amount) | ||||||
|  |         internal | ||||||
|  |     { | ||||||
|  |         if (amount > 0) { | ||||||
|  |             (bool success,) = recipient.call{value: amount}(""); | ||||||
|  |             require(success, "FixinTokenSpender::_transferEth/TRANSFER_FAILED"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// @dev Gets the maximum amount of an ERC20 token `token` that can be |     /// @dev Gets the maximum amount of an ERC20 token `token` that can be | ||||||
|     ///      pulled from `owner` by this address. |     ///      pulled from `owner` by this address. | ||||||
|     /// @param token The token to spend. |     /// @param token The token to spend. | ||||||
|   | |||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./LibStorage.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Storage helpers for `ERC1155OrdersFeature`. | ||||||
|  | library LibERC1155OrdersStorage { | ||||||
|  |  | ||||||
|  |     struct OrderState { | ||||||
|  |         // The amount (denominated in the ERC1155 asset) | ||||||
|  |         // that the order has been filled by. | ||||||
|  |         uint128 filledAmount; | ||||||
|  |         // Whether the order has been pre-signed. | ||||||
|  |         bool preSigned; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Storage bucket for this feature. | ||||||
|  |     struct Storage { | ||||||
|  |         // Mapping from order hash to order state: | ||||||
|  |         mapping(bytes32 => OrderState) orderState; | ||||||
|  |         // maker => nonce range => order cancellation bit vector | ||||||
|  |         mapping(address => mapping(uint248 => uint256)) orderCancellationByMaker; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the storage bucket for this contract. | ||||||
|  |     function getStorage() internal pure returns (Storage storage stor) { | ||||||
|  |         uint256 storageSlot = LibStorage.getStorageSlot( | ||||||
|  |             LibStorage.StorageId.ERC1155Orders | ||||||
|  |         ); | ||||||
|  |         // Dip into assembly to change the slot pointed to by the local | ||||||
|  |         // variable `stor`. | ||||||
|  |         // See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries | ||||||
|  |         assembly { stor_slot := storageSlot } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,47 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./LibStorage.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /// @dev Storage helpers for `ERC721OrdersFeature`. | ||||||
|  | library LibERC721OrdersStorage { | ||||||
|  |  | ||||||
|  |     /// @dev Storage bucket for this feature. | ||||||
|  |     struct Storage { | ||||||
|  |         // maker => nonce range => order status bit vector | ||||||
|  |         mapping(address => mapping(uint248 => uint256)) orderStatusByMaker; | ||||||
|  |         // order hash => isSigned | ||||||
|  |         mapping(bytes32 => bool) preSigned; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Get the storage bucket for this contract. | ||||||
|  |     function getStorage() internal pure returns (Storage storage stor) { | ||||||
|  |         uint256 storageSlot = LibStorage.getStorageSlot( | ||||||
|  |             LibStorage.StorageId.ERC721Orders | ||||||
|  |         ); | ||||||
|  |         // Dip into assembly to change the slot pointed to by the local | ||||||
|  |         // variable `stor`. | ||||||
|  |         // See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries | ||||||
|  |         assembly { stor_slot := storageSlot } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|  |  | ||||||
| */ | */ | ||||||
|  |  | ||||||
| pragma solidity ^0.6.5; | pragma solidity ^0.6; | ||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -39,7 +39,9 @@ library LibStorage { | |||||||
|         MetaTransactions, |         MetaTransactions, | ||||||
|         ReentrancyGuard, |         ReentrancyGuard, | ||||||
|         NativeOrders, |         NativeOrders, | ||||||
|         OtcOrders |         OtcOrders, | ||||||
|  |         ERC721Orders, | ||||||
|  |         ERC1155Orders | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// @dev Get the storage slot given a storage ID. We assign unique, well-spaced |     /// @dev Get the storage slot given a storage ID. We assign unique, well-spaced | ||||||
|   | |||||||
| @@ -313,7 +313,7 @@ contract FillQuoteTransformer is | |||||||
|         if (success) { |         if (success) { | ||||||
|             results.makerTokenBoughtAmount = abi.decode(resultData, (uint256)); |             results.makerTokenBoughtAmount = abi.decode(resultData, (uint256)); | ||||||
|             results.takerTokenSoldAmount = takerTokenFillAmount; |             results.takerTokenSoldAmount = takerTokenFillAmount; | ||||||
|         } |         }  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Fill a single limit order. |     // Fill a single limit order. | ||||||
|   | |||||||
| @@ -0,0 +1,88 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./IBridgeAdapter.sol"; | ||||||
|  |  | ||||||
|  | abstract contract AbstractBridgeAdapter is IBridgeAdapter { | ||||||
|  |  | ||||||
|  |     constructor( | ||||||
|  |         uint256 expectedChainId,  | ||||||
|  |         string memory expectedChainName | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |     { | ||||||
|  |         uint256 chainId; | ||||||
|  |         assembly { chainId := chainid() } | ||||||
|  |         // Allow testing on Ganache | ||||||
|  |         if (chainId != expectedChainId && chainId != 1337) { | ||||||
|  |             revert(string(abi.encodePacked(expectedChainName, "BridgeAdapter.constructor: wrong chain ID"))); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function isSupportedSource(bytes32 source) | ||||||
|  |         external | ||||||
|  |         override | ||||||
|  |         returns (bool isSupported) | ||||||
|  |     { | ||||||
|  |         BridgeOrder memory placeholderOrder; | ||||||
|  |         placeholderOrder.source = source; | ||||||
|  |         IERC20TokenV06 placeholderToken = IERC20TokenV06(address(0)); | ||||||
|  |          | ||||||
|  |         (, isSupported) = _trade( | ||||||
|  |             placeholderOrder, | ||||||
|  |             placeholderToken, | ||||||
|  |             placeholderToken, | ||||||
|  |             0, | ||||||
|  |             true | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |         (boughtAmount, ) = _trade( | ||||||
|  |             order, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             false | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         virtual | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource); | ||||||
|  | } | ||||||
| @@ -0,0 +1,151 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./AbstractBridgeAdapter.sol"; | ||||||
|  | import "./BridgeProtocols.sol"; | ||||||
|  | import "./mixins/MixinCurve.sol"; | ||||||
|  | import "./mixins/MixinCurveV2.sol"; | ||||||
|  | import "./mixins/MixinGMX.sol"; | ||||||
|  | import "./mixins/MixinKyberDmm.sol"; | ||||||
|  | import "./mixins/MixinAaveV2.sol"; | ||||||
|  | import "./mixins/MixinNerve.sol"; | ||||||
|  | import "./mixins/MixinPlatypus.sol"; | ||||||
|  | import "./mixins/MixinUniswapV2.sol"; | ||||||
|  | import "./mixins/MixinWOOFi.sol"; | ||||||
|  | import "./mixins/MixinZeroExBridge.sol"; | ||||||
|  |  | ||||||
|  | contract AvalancheBridgeAdapter is | ||||||
|  |     AbstractBridgeAdapter(43114, "Avalanche"), | ||||||
|  |     MixinCurve, | ||||||
|  |     MixinCurveV2, | ||||||
|  |     MixinGMX, | ||||||
|  |     MixinKyberDmm, | ||||||
|  |     MixinAaveV2, | ||||||
|  |     MixinNerve, | ||||||
|  |     MixinPlatypus, | ||||||
|  |     MixinUniswapV2, | ||||||
|  |     MixinWOOFi, | ||||||
|  |     MixinZeroExBridge | ||||||
|  | { | ||||||
|  |     constructor(IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         MixinCurve(weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|  |     { | ||||||
|  |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|  |         if (protocolId == BridgeProtocols.CURVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurve( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.CURVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNISWAPV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV2( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeNerve( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.KYBERDMM) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeKyberDmm( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.AAVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeAaveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.GMX) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeGMX( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.PLATYPUS) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradePlatypus( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.WOOFI) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeWOOFi( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); }             | ||||||
|  |             boughtAmount = _tradeZeroExBridge( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit BridgeFill( | ||||||
|  |             order.source, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             boughtAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,142 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./AbstractBridgeAdapter.sol"; | ||||||
|  | import "./BridgeProtocols.sol"; | ||||||
|  | import "./mixins/MixinCurve.sol"; | ||||||
|  | import "./mixins/MixinDodo.sol"; | ||||||
|  | import "./mixins/MixinDodoV2.sol"; | ||||||
|  | import "./mixins/MixinKyberDmm.sol"; | ||||||
|  | import "./mixins/MixinMooniswap.sol"; | ||||||
|  | import "./mixins/MixinNerve.sol"; | ||||||
|  | import "./mixins/MixinUniswapV2.sol"; | ||||||
|  | import "./mixins/MixinWOOFi.sol"; | ||||||
|  | import "./mixins/MixinZeroExBridge.sol"; | ||||||
|  |  | ||||||
|  | contract BSCBridgeAdapter is | ||||||
|  |     AbstractBridgeAdapter(56, "BSC"), | ||||||
|  |     MixinCurve, | ||||||
|  |     MixinDodo, | ||||||
|  |     MixinDodoV2, | ||||||
|  |     MixinKyberDmm, | ||||||
|  |     MixinMooniswap, | ||||||
|  |     MixinNerve, | ||||||
|  |     MixinUniswapV2, | ||||||
|  |     MixinWOOFi, | ||||||
|  |     MixinZeroExBridge | ||||||
|  | { | ||||||
|  |     constructor(IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         MixinCurve(weth) | ||||||
|  |         MixinMooniswap(weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|  |     { | ||||||
|  |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|  |         if (protocolId == BridgeProtocols.CURVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurve( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNISWAPV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV2( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.MOONISWAP) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeMooniswap( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.DODO) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeDodo( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.DODOV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeDodoV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeNerve( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.KYBERDMM) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeKyberDmm( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.WOOFI) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeWOOFi( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeZeroExBridge( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit BridgeFill( | ||||||
|  |             order.source, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             boughtAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -27,29 +27,36 @@ library BridgeProtocols { | |||||||
|     // A incrementally increasing, append-only list of protocol IDs. |     // A incrementally increasing, append-only list of protocol IDs. | ||||||
|     // We don't use an enum so solidity doesn't throw when we pass in a |     // We don't use an enum so solidity doesn't throw when we pass in a | ||||||
|     // new protocol ID that hasn't been rolled up yet. |     // new protocol ID that hasn't been rolled up yet. | ||||||
|     uint128 internal constant UNKNOWN     = 0; |     uint128 internal constant UNKNOWN         = 0; | ||||||
|     uint128 internal constant CURVE       = 1; |     uint128 internal constant CURVE           = 1; | ||||||
|     uint128 internal constant UNISWAPV2   = 2; |     uint128 internal constant UNISWAPV2       = 2; | ||||||
|     uint128 internal constant UNISWAP     = 3; |     uint128 internal constant UNISWAP         = 3; | ||||||
|     uint128 internal constant BALANCER    = 4; |     uint128 internal constant BALANCER        = 4; | ||||||
|     uint128 internal constant KYBER       = 5; |     uint128 internal constant KYBER           = 5;  // Not used: deprecated. | ||||||
|     uint128 internal constant MOONISWAP   = 6; |     uint128 internal constant MOONISWAP       = 6; | ||||||
|     uint128 internal constant MSTABLE     = 7; |     uint128 internal constant MSTABLE         = 7; | ||||||
|     uint128 internal constant OASIS       = 8; |     uint128 internal constant OASIS           = 8;  // Not used: deprecated. | ||||||
|     uint128 internal constant SHELL       = 9; |     uint128 internal constant SHELL           = 9; | ||||||
|     uint128 internal constant DODO        = 10; |     uint128 internal constant DODO            = 10; | ||||||
|     uint128 internal constant DODOV2      = 11; |     uint128 internal constant DODOV2          = 11; | ||||||
|     uint128 internal constant CRYPTOCOM   = 12; |     uint128 internal constant CRYPTOCOM       = 12; | ||||||
|     uint128 internal constant BANCOR      = 13; |     uint128 internal constant BANCOR          = 13; | ||||||
|     uint128 internal constant COFIX       = 14; |     uint128 internal constant COFIX           = 14; // Not used: deprecated. | ||||||
|     uint128 internal constant NERVE       = 15; |     uint128 internal constant NERVE           = 15; | ||||||
|     uint128 internal constant MAKERPSM    = 16; |     uint128 internal constant MAKERPSM        = 16; | ||||||
|     uint128 internal constant BALANCERV2  = 17; |     uint128 internal constant BALANCERV2      = 17; | ||||||
|     uint128 internal constant UNISWAPV3   = 18; |     uint128 internal constant UNISWAPV3       = 18; | ||||||
|     uint128 internal constant KYBERDMM    = 19; |     uint128 internal constant KYBERDMM        = 19; | ||||||
|     uint128 internal constant CURVEV2     = 20; |     uint128 internal constant CURVEV2         = 20; | ||||||
|     uint128 internal constant LIDO        = 21; |     uint128 internal constant LIDO            = 21; | ||||||
|     uint128 internal constant CLIPPER     = 22; // Not used: Clipper is now using PLP interface |     uint128 internal constant CLIPPER         = 22; // Not used: Clipper is now using PLP interface | ||||||
|     uint128 internal constant AAVEV2      = 23; |     uint128 internal constant AAVEV2          = 23; | ||||||
|     uint128 internal constant COMPOUND    = 24; |     uint128 internal constant COMPOUND        = 24; | ||||||
|  |     uint128 internal constant BALANCERV2BATCH = 25; | ||||||
|  |     uint128 internal constant GMX             = 26; | ||||||
|  |     uint128 internal constant PLATYPUS        = 27; | ||||||
|  |     uint128 internal constant BANCORV3        = 28; | ||||||
|  |     uint128 internal constant VELODROME       = 29; | ||||||
|  |     uint128 internal constant SYNTHETIX       = 30; | ||||||
|  |     uint128 internal constant WOOFI           = 31; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,84 @@ | |||||||
|  |  | ||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./AbstractBridgeAdapter.sol"; | ||||||
|  | import "./BridgeProtocols.sol"; | ||||||
|  | import "./mixins/MixinNerve.sol"; | ||||||
|  | import "./mixins/MixinUniswapV2.sol"; | ||||||
|  | import "./mixins/MixinZeroExBridge.sol"; | ||||||
|  |  | ||||||
|  | contract CeloBridgeAdapter is | ||||||
|  |     AbstractBridgeAdapter(42220, "Celo"), | ||||||
|  |     MixinNerve, | ||||||
|  |     MixinUniswapV2, | ||||||
|  |     MixinZeroExBridge | ||||||
|  | { | ||||||
|  |     constructor(address _weth) | ||||||
|  |         public | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|  |     { | ||||||
|  |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|  |         if (protocolId == BridgeProtocols.UNISWAPV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV2( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeNerve( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); }             | ||||||
|  |             boughtAmount = _tradeZeroExBridge( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit BridgeFill( | ||||||
|  |             order.source, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             boughtAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| // SPDX-License-Identifier: Apache-2.0 | // SPDX-License-Identifier: Apache-2.0 | ||||||
| /* | /* | ||||||
| 
 | 
 | ||||||
|   Copyright 2021 ZeroEx Intl. |   Copyright 2022 ZeroEx Intl. | ||||||
| 
 | 
 | ||||||
|   Licensed under the Apache License, Version 2.0 (the "License"); |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|   you may not use this file except in compliance with the License. |   you may not use this file except in compliance with the License. | ||||||
| @@ -20,55 +20,53 @@ | |||||||
| pragma solidity ^0.6.5; | pragma solidity ^0.6.5; | ||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
| 
 | 
 | ||||||
| import "./IBridgeAdapter.sol"; | import "./AbstractBridgeAdapter.sol"; | ||||||
| import "./BridgeProtocols.sol"; | import "./BridgeProtocols.sol"; | ||||||
| import "./mixins/MixinAaveV2.sol"; | import "./mixins/MixinAaveV2.sol"; | ||||||
| import "./mixins/MixinBalancer.sol"; | import "./mixins/MixinBalancer.sol"; | ||||||
| import "./mixins/MixinBalancerV2.sol"; | import "./mixins/MixinBalancerV2.sol"; | ||||||
|  | import "./mixins/MixinBalancerV2Batch.sol"; | ||||||
| import "./mixins/MixinBancor.sol"; | import "./mixins/MixinBancor.sol"; | ||||||
| import "./mixins/MixinCoFiX.sol"; | import "./mixins/MixinBancorV3.sol"; | ||||||
| import "./mixins/MixinCompound.sol"; | import "./mixins/MixinCompound.sol"; | ||||||
| import "./mixins/MixinCurve.sol"; | import "./mixins/MixinCurve.sol"; | ||||||
| import "./mixins/MixinCurveV2.sol"; | import "./mixins/MixinCurveV2.sol"; | ||||||
| import "./mixins/MixinCryptoCom.sol"; | import "./mixins/MixinCryptoCom.sol"; | ||||||
| import "./mixins/MixinDodo.sol"; | import "./mixins/MixinDodo.sol"; | ||||||
| import "./mixins/MixinDodoV2.sol"; | import "./mixins/MixinDodoV2.sol"; | ||||||
| import "./mixins/MixinKyber.sol"; |  | ||||||
| import "./mixins/MixinKyberDmm.sol"; | import "./mixins/MixinKyberDmm.sol"; | ||||||
| import "./mixins/MixinLido.sol"; | import "./mixins/MixinLido.sol"; | ||||||
| import "./mixins/MixinMakerPSM.sol"; | import "./mixins/MixinMakerPSM.sol"; | ||||||
| import "./mixins/MixinMooniswap.sol"; |  | ||||||
| import "./mixins/MixinMStable.sol"; | import "./mixins/MixinMStable.sol"; | ||||||
| import "./mixins/MixinNerve.sol"; | import "./mixins/MixinNerve.sol"; | ||||||
| import "./mixins/MixinOasis.sol"; |  | ||||||
| import "./mixins/MixinShell.sol"; | import "./mixins/MixinShell.sol"; | ||||||
|  | import "./mixins/MixinSynthetix.sol"; | ||||||
| import "./mixins/MixinUniswap.sol"; | import "./mixins/MixinUniswap.sol"; | ||||||
| import "./mixins/MixinUniswapV2.sol"; | import "./mixins/MixinUniswapV2.sol"; | ||||||
| import "./mixins/MixinUniswapV3.sol"; | import "./mixins/MixinUniswapV3.sol"; | ||||||
| import "./mixins/MixinZeroExBridge.sol"; | import "./mixins/MixinZeroExBridge.sol"; | ||||||
| 
 | 
 | ||||||
| contract BridgeAdapter is | contract EthereumBridgeAdapter is | ||||||
|     IBridgeAdapter, |     AbstractBridgeAdapter(1, "Ethereum"), | ||||||
|     MixinAaveV2, |     MixinAaveV2, | ||||||
|     MixinBalancer, |     MixinBalancer, | ||||||
|     MixinBalancerV2, |     MixinBalancerV2, | ||||||
|  |     MixinBalancerV2Batch, | ||||||
|     MixinBancor, |     MixinBancor, | ||||||
|     MixinCoFiX, |     MixinBancorV3, | ||||||
|     MixinCompound, |     MixinCompound, | ||||||
|     MixinCurve, |     MixinCurve, | ||||||
|     MixinCurveV2, |     MixinCurveV2, | ||||||
|     MixinCryptoCom, |     MixinCryptoCom, | ||||||
|     MixinDodo, |     MixinDodo, | ||||||
|     MixinDodoV2, |     MixinDodoV2, | ||||||
|     MixinKyber, |  | ||||||
|     MixinKyberDmm, |     MixinKyberDmm, | ||||||
|     MixinLido, |     MixinLido, | ||||||
|     MixinMakerPSM, |     MixinMakerPSM, | ||||||
|     MixinMooniswap, |  | ||||||
|     MixinMStable, |     MixinMStable, | ||||||
|     MixinNerve, |     MixinNerve, | ||||||
|     MixinOasis, |  | ||||||
|     MixinShell, |     MixinShell, | ||||||
|  |     MixinSynthetix, | ||||||
|     MixinUniswap, |     MixinUniswap, | ||||||
|     MixinUniswapV2, |     MixinUniswapV2, | ||||||
|     MixinUniswapV3, |     MixinUniswapV3, | ||||||
| @@ -76,43 +74,28 @@ contract BridgeAdapter is | |||||||
| { | { | ||||||
|     constructor(IEtherTokenV06 weth) |     constructor(IEtherTokenV06 weth) | ||||||
|         public |         public | ||||||
|         MixinAaveV2() |  | ||||||
|         MixinBalancer() |  | ||||||
|         MixinBalancerV2() |  | ||||||
|         MixinBancor(weth) |         MixinBancor(weth) | ||||||
|         MixinCoFiX() |         MixinBancorV3(weth) | ||||||
|         MixinCompound(weth) |         MixinCompound(weth) | ||||||
|         MixinCurve(weth) |         MixinCurve(weth) | ||||||
|         MixinCurveV2() |  | ||||||
|         MixinCryptoCom() |  | ||||||
|         MixinDodo() |  | ||||||
|         MixinDodoV2() |  | ||||||
|         MixinKyber(weth) |  | ||||||
|         MixinLido(weth) |         MixinLido(weth) | ||||||
|         MixinMakerPSM() |  | ||||||
|         MixinMooniswap(weth) |  | ||||||
|         MixinMStable() |  | ||||||
|         MixinNerve() |  | ||||||
|         MixinOasis() |  | ||||||
|         MixinShell() |  | ||||||
|         MixinUniswap(weth) |         MixinUniswap(weth) | ||||||
|         MixinUniswapV2() |  | ||||||
|         MixinUniswapV3() |  | ||||||
|         MixinZeroExBridge() |  | ||||||
|     {} |     {} | ||||||
| 
 | 
 | ||||||
|     function trade( |     function _trade( | ||||||
|         BridgeOrder memory order, |         BridgeOrder memory order, | ||||||
|         IERC20TokenV06 sellToken, |         IERC20TokenV06 sellToken, | ||||||
|         IERC20TokenV06 buyToken, |         IERC20TokenV06 buyToken, | ||||||
|         uint256 sellAmount |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|     ) |     ) | ||||||
|         public |         internal | ||||||
|         override |         override | ||||||
|         returns (uint256 boughtAmount) |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|     { |     { | ||||||
|         uint128 protocolId = uint128(uint256(order.source) >> 128); |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|         if (protocolId == BridgeProtocols.CURVE) { |         if (protocolId == BridgeProtocols.CURVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeCurve( |             boughtAmount = _tradeCurve( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -120,6 +103,7 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.CURVEV2) { |         } else if (protocolId == BridgeProtocols.CURVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeCurveV2( |             boughtAmount = _tradeCurveV2( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -127,18 +111,21 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.UNISWAPV3) { |         } else if (protocolId == BridgeProtocols.UNISWAPV3) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeUniswapV3( |             boughtAmount = _tradeUniswapV3( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.UNISWAPV2) { |         } else if (protocolId == BridgeProtocols.UNISWAPV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeUniswapV2( |             boughtAmount = _tradeUniswapV2( | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.UNISWAP) { |         } else if (protocolId == BridgeProtocols.UNISWAP) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeUniswap( |             boughtAmount = _tradeUniswap( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -146,6 +133,7 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.BALANCER) { |         } else if (protocolId == BridgeProtocols.BALANCER) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeBalancer( |             boughtAmount = _tradeBalancer( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -153,48 +141,37 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.BALANCERV2) { |         } else if (protocolId == BridgeProtocols.BALANCERV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeBalancerV2( |             boughtAmount = _tradeBalancerV2( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.KYBER) { |         } else if (protocolId == BridgeProtocols.BALANCERV2BATCH) { | ||||||
|             boughtAmount = _tradeKyber( |             if (dryRun) { return (0, true); } | ||||||
|                 sellToken, |             boughtAmount = _tradeBalancerV2Batch( | ||||||
|                 buyToken, |  | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.MAKERPSM) { |         } else if (protocolId == BridgeProtocols.MAKERPSM) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeMakerPsm( |             boughtAmount = _tradeMakerPsm( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.MOONISWAP) { |  | ||||||
|             boughtAmount = _tradeMooniswap( |  | ||||||
|                 sellToken, |  | ||||||
|                 buyToken, |  | ||||||
|                 sellAmount, |  | ||||||
|                 order.bridgeData |  | ||||||
|             ); |  | ||||||
|         } else if (protocolId == BridgeProtocols.MSTABLE) { |         } else if (protocolId == BridgeProtocols.MSTABLE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeMStable( |             boughtAmount = _tradeMStable( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.OASIS) { |  | ||||||
|             boughtAmount = _tradeOasis( |  | ||||||
|                 sellToken, |  | ||||||
|                 buyToken, |  | ||||||
|                 sellAmount, |  | ||||||
|                 order.bridgeData |  | ||||||
|             ); |  | ||||||
|         } else if (protocolId == BridgeProtocols.SHELL) { |         } else if (protocolId == BridgeProtocols.SHELL) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeShell( |             boughtAmount = _tradeShell( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -202,49 +179,49 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.DODO) { |         } else if (protocolId == BridgeProtocols.DODO) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeDodo( |             boughtAmount = _tradeDodo( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.DODOV2) { |         } else if (protocolId == BridgeProtocols.DODOV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeDodoV2( |             boughtAmount = _tradeDodoV2( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.CRYPTOCOM) { |         } else if (protocolId == BridgeProtocols.CRYPTOCOM) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeCryptoCom( |             boughtAmount = _tradeCryptoCom( | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.BANCOR) { |         } else if (protocolId == BridgeProtocols.BANCOR) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeBancor( |             boughtAmount = _tradeBancor( | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.COFIX) { |  | ||||||
|             boughtAmount = _tradeCoFiX( |  | ||||||
|                 sellToken, |  | ||||||
|                 buyToken, |  | ||||||
|                 sellAmount, |  | ||||||
|                 order.bridgeData |  | ||||||
|             ); |  | ||||||
|         } else if (protocolId == BridgeProtocols.NERVE) { |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeNerve( |             boughtAmount = _tradeNerve( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.KYBERDMM) { |         } else if (protocolId == BridgeProtocols.KYBERDMM) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeKyberDmm( |             boughtAmount = _tradeKyberDmm( | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.LIDO) { |         } else if (protocolId == BridgeProtocols.LIDO) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeLido( |             boughtAmount = _tradeLido( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -252,6 +229,7 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.AAVEV2) { |         } else if (protocolId == BridgeProtocols.AAVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeAaveV2( |             boughtAmount = _tradeAaveV2( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -259,13 +237,28 @@ contract BridgeAdapter is | |||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else if (protocolId == BridgeProtocols.COMPOUND) { |         } else if (protocolId == BridgeProtocols.COMPOUND) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeCompound( |             boughtAmount = _tradeCompound( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
|                 sellAmount, |                 sellAmount, | ||||||
|                 order.bridgeData |                 order.bridgeData | ||||||
|             ); |             ); | ||||||
|         } else { |         } else if (protocolId == BridgeProtocols.BANCORV3) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeBancorV3( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.SYNTHETIX) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeSynthetix( | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|             boughtAmount = _tradeZeroExBridge( |             boughtAmount = _tradeZeroExBridge( | ||||||
|                 sellToken, |                 sellToken, | ||||||
|                 buyToken, |                 buyToken, | ||||||
| @@ -0,0 +1,134 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./AbstractBridgeAdapter.sol"; | ||||||
|  | import "./BridgeProtocols.sol"; | ||||||
|  | import "./mixins/MixinAaveV2.sol"; | ||||||
|  | import "./mixins/MixinBalancerV2.sol"; | ||||||
|  | import "./mixins/MixinCurve.sol"; | ||||||
|  | import "./mixins/MixinCurveV2.sol"; | ||||||
|  | import "./mixins/MixinNerve.sol"; | ||||||
|  | import "./mixins/MixinUniswapV2.sol"; | ||||||
|  | import "./mixins/MixinWOOFi.sol"; | ||||||
|  | import "./mixins/MixinZeroExBridge.sol"; | ||||||
|  |  | ||||||
|  | contract FantomBridgeAdapter is | ||||||
|  |     AbstractBridgeAdapter(250, "Fantom"), | ||||||
|  |     MixinAaveV2, | ||||||
|  |     MixinBalancerV2, | ||||||
|  |     MixinCurve, | ||||||
|  |     MixinCurveV2, | ||||||
|  |     MixinNerve, | ||||||
|  |     MixinUniswapV2, | ||||||
|  |     MixinWOOFi, | ||||||
|  |     MixinZeroExBridge | ||||||
|  | { | ||||||
|  |     constructor(IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         MixinCurve(weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|  |     { | ||||||
|  |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|  |         if (protocolId == BridgeProtocols.CURVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurve( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.CURVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNISWAPV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV2( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.BALANCERV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeBalancerV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeNerve( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.AAVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeAaveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.WOOFI) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeWOOFi( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); }             | ||||||
|  |             boughtAmount = _tradeZeroExBridge( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit BridgeFill( | ||||||
|  |             order.source, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             boughtAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -50,6 +50,10 @@ interface IBridgeAdapter { | |||||||
|         uint256 outputTokenAmount |         uint256 outputTokenAmount | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     function isSupportedSource(bytes32 source) | ||||||
|  |         external | ||||||
|  |         returns (bool isSupported); | ||||||
|  |  | ||||||
|     function trade( |     function trade( | ||||||
|         BridgeOrder calldata order, |         BridgeOrder calldata order, | ||||||
|         IERC20TokenV06 sellToken, |         IERC20TokenV06 sellToken, | ||||||
|   | |||||||
| @@ -0,0 +1,122 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./AbstractBridgeAdapter.sol"; | ||||||
|  | import "./BridgeProtocols.sol"; | ||||||
|  | import "./mixins/MixinCurve.sol"; | ||||||
|  | import "./mixins/MixinCurveV2.sol"; | ||||||
|  | import "./mixins/MixinNerve.sol"; | ||||||
|  | import "./mixins/MixinSynthetix.sol"; | ||||||
|  | import "./mixins/MixinUniswapV3.sol"; | ||||||
|  | import "./mixins/MixinVelodrome.sol"; | ||||||
|  | import "./mixins/MixinZeroExBridge.sol"; | ||||||
|  |  | ||||||
|  | contract OptimismBridgeAdapter is | ||||||
|  |     AbstractBridgeAdapter(10, "Optimism"), | ||||||
|  |     MixinCurve, | ||||||
|  |     MixinCurveV2, | ||||||
|  |     MixinNerve, | ||||||
|  |     MixinSynthetix, | ||||||
|  |     MixinUniswapV3, | ||||||
|  |     MixinVelodrome, | ||||||
|  |     MixinZeroExBridge | ||||||
|  | { | ||||||
|  |     constructor(IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         MixinCurve(weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|  |     { | ||||||
|  |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|  |         if (protocolId == BridgeProtocols.CURVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurve( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.CURVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNISWAPV3) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV3( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeNerve( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.VELODROME) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeVelodrome( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.SYNTHETIX) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeSynthetix( | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); }             | ||||||
|  |             boughtAmount = _tradeZeroExBridge( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit BridgeFill( | ||||||
|  |             order.source, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             boughtAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,188 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "./AbstractBridgeAdapter.sol"; | ||||||
|  | import "./BridgeProtocols.sol"; | ||||||
|  | import "./mixins/MixinAaveV2.sol"; | ||||||
|  | import "./mixins/MixinBalancerV2.sol"; | ||||||
|  | import "./mixins/MixinBalancerV2Batch.sol"; | ||||||
|  | import "./mixins/MixinCurve.sol"; | ||||||
|  | import "./mixins/MixinCurveV2.sol"; | ||||||
|  | import "./mixins/MixinDodo.sol"; | ||||||
|  | import "./mixins/MixinDodoV2.sol"; | ||||||
|  | import "./mixins/MixinKyberDmm.sol"; | ||||||
|  | import "./mixins/MixinMStable.sol"; | ||||||
|  | import "./mixins/MixinNerve.sol"; | ||||||
|  | import "./mixins/MixinUniswapV2.sol"; | ||||||
|  | import "./mixins/MixinUniswapV3.sol"; | ||||||
|  | import "./mixins/MixinWOOFi.sol"; | ||||||
|  | import "./mixins/MixinZeroExBridge.sol"; | ||||||
|  |  | ||||||
|  | contract PolygonBridgeAdapter is | ||||||
|  |     AbstractBridgeAdapter(137, "Polygon"), | ||||||
|  |     MixinAaveV2, | ||||||
|  |     MixinBalancerV2, | ||||||
|  |     MixinBalancerV2Batch, | ||||||
|  |     MixinCurve, | ||||||
|  |     MixinCurveV2, | ||||||
|  |     MixinDodo, | ||||||
|  |     MixinDodoV2, | ||||||
|  |     MixinKyberDmm, | ||||||
|  |     MixinMStable, | ||||||
|  |     MixinNerve, | ||||||
|  |     MixinUniswapV2, | ||||||
|  |     MixinUniswapV3, | ||||||
|  |     MixinWOOFi, | ||||||
|  |     MixinZeroExBridge | ||||||
|  | { | ||||||
|  |     constructor(IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |         MixinCurve(weth) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     function _trade( | ||||||
|  |         BridgeOrder memory order, | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bool dryRun | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         override | ||||||
|  |         returns (uint256 boughtAmount, bool supportedSource) | ||||||
|  |     { | ||||||
|  |         uint128 protocolId = uint128(uint256(order.source) >> 128); | ||||||
|  |         if (protocolId == BridgeProtocols.CURVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurve( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.CURVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeCurveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNISWAPV3) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV3( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNISWAPV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeUniswapV2( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.BALANCERV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeBalancerV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.BALANCERV2BATCH) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeBalancerV2Batch( | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.MSTABLE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeMStable( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.DODO) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeDodo( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.DODOV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeDodoV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.NERVE) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeNerve( | ||||||
|  |                 sellToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.KYBERDMM) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeKyberDmm( | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.AAVEV2) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeAaveV2( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.WOOFI) { | ||||||
|  |             if (dryRun) { return (0, true); } | ||||||
|  |             boughtAmount = _tradeWOOFi( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } else if (protocolId == BridgeProtocols.UNKNOWN) { | ||||||
|  |             if (dryRun) { return (0, true); }             | ||||||
|  |             boughtAmount = _tradeZeroExBridge( | ||||||
|  |                 sellToken, | ||||||
|  |                 buyToken, | ||||||
|  |                 sellAmount, | ||||||
|  |                 order.bridgeData | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         emit BridgeFill( | ||||||
|  |             order.source, | ||||||
|  |             sellToken, | ||||||
|  |             buyToken, | ||||||
|  |             sellAmount, | ||||||
|  |             boughtAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,107 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IBalancerV2BatchSwapVault { | ||||||
|  |  | ||||||
|  |     enum SwapKind { GIVEN_IN, GIVEN_OUT } | ||||||
|  |  | ||||||
|  |     struct BatchSwapStep { | ||||||
|  |         bytes32 poolId; | ||||||
|  |         uint256 assetInIndex; | ||||||
|  |         uint256 assetOutIndex; | ||||||
|  |         uint256 amount; | ||||||
|  |         bytes userData; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     struct FundManagement { | ||||||
|  |         address sender; | ||||||
|  |         bool fromInternalBalance; | ||||||
|  |         address payable recipient; | ||||||
|  |         bool toInternalBalance; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function batchSwap( | ||||||
|  |         SwapKind kind, | ||||||
|  |         BatchSwapStep[] calldata swaps, | ||||||
|  |         IERC20TokenV06[] calldata assets, | ||||||
|  |         FundManagement calldata funds, | ||||||
|  |         int256[] calldata limits, | ||||||
|  |         uint256 deadline | ||||||
|  |     ) external returns (int256[] memory amounts); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinBalancerV2Batch { | ||||||
|  |  | ||||||
|  |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
|  |  | ||||||
|  |     struct BalancerV2BatchBridgeData { | ||||||
|  |         IBalancerV2BatchSwapVault vault; | ||||||
|  |         IBalancerV2BatchSwapVault.BatchSwapStep[] swapSteps; | ||||||
|  |         IERC20TokenV06[] assets; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _tradeBalancerV2Batch( | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |         // Decode the bridge data. | ||||||
|  |         ( | ||||||
|  |             IBalancerV2BatchSwapVault vault, | ||||||
|  |             IBalancerV2BatchSwapVault.BatchSwapStep[] memory swapSteps, | ||||||
|  |             address[] memory assets_ | ||||||
|  |         ) = abi.decode(bridgeData, (IBalancerV2BatchSwapVault, IBalancerV2BatchSwapVault.BatchSwapStep[], address[])); | ||||||
|  |         IERC20TokenV06[] memory assets; | ||||||
|  |         assembly { assets := assets_ } | ||||||
|  |  | ||||||
|  |         // Grant an allowance to the exchange to spend `fromTokenAddress` token. | ||||||
|  |         assets[0].approveIfBelow(address(vault), sellAmount); | ||||||
|  |  | ||||||
|  |         swapSteps[0].amount = sellAmount; | ||||||
|  |         int256[] memory limits = new int256[](assets.length); | ||||||
|  |         for (uint256 i = 0; i < limits.length; ++i) { | ||||||
|  |             limits[i] = type(int256).max; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         int256[] memory amounts = vault.batchSwap( | ||||||
|  |             IBalancerV2BatchSwapVault.SwapKind.GIVEN_IN, | ||||||
|  |             swapSteps, | ||||||
|  |             assets, | ||||||
|  |             IBalancerV2BatchSwapVault.FundManagement({ | ||||||
|  |                 sender: address(this), | ||||||
|  |                 fromInternalBalance: false, | ||||||
|  |                 recipient: payable(address(this)), | ||||||
|  |                 toInternalBalance: false | ||||||
|  |             }), | ||||||
|  |             limits, | ||||||
|  |             block.timestamp + 1 | ||||||
|  |         ); | ||||||
|  |         require(amounts[amounts.length - 1] <= 0, 'Unexpected BalancerV2Batch output'); | ||||||
|  |         return uint256(amounts[amounts.length - 1] * -1); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,128 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |     BancorV3 | ||||||
|  | */ | ||||||
|  | interface IBancorV3 { | ||||||
|  |     /** | ||||||
|  |      * @dev performs a trade by providing the source amount and returns the target amount and the associated fee | ||||||
|  |      * | ||||||
|  |      * requirements: | ||||||
|  |      * | ||||||
|  |      * - the caller must be the network contract | ||||||
|  |      */ | ||||||
|  |     function tradeBySourceAmount( | ||||||
|  |         address sourceToken, | ||||||
|  |         address targetToken, | ||||||
|  |         uint256 sourceAmount, | ||||||
|  |         uint256 minReturnAmount, | ||||||
|  |         uint256 deadline, | ||||||
|  |         address beneficiary | ||||||
|  |     ) external payable returns (uint256 amount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinBancorV3 { | ||||||
|  |  | ||||||
|  |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
|  |  | ||||||
|  |     IERC20TokenV06 constant public BANCORV3_ETH_ADDRESS = | ||||||
|  |         IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); | ||||||
|  |     IEtherTokenV06 private immutable WETH; | ||||||
|  |  | ||||||
|  |     constructor(IEtherTokenV06 weth) | ||||||
|  |         public | ||||||
|  |     { | ||||||
|  |         WETH = weth; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _tradeBancorV3( | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         returns (uint256 amountOut) | ||||||
|  |  | ||||||
|  |     { | ||||||
|  |         IBancorV3 router; | ||||||
|  |         IERC20TokenV06[] memory path; | ||||||
|  |         address[] memory _path; | ||||||
|  |         uint256 payableAmount = 0; | ||||||
|  |  | ||||||
|  |         { | ||||||
|  |             (router, _path) = abi.decode(bridgeData, (IBancorV3, address[])); | ||||||
|  |             // To get around `abi.decode()` not supporting interface array types. | ||||||
|  |             assembly { path := _path } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         require(path.length >= 2, "MixinBancorV3/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||||
|  |         require( | ||||||
|  |             path[path.length - 1] == buyToken, | ||||||
|  |             "MixinBancorV3/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         //swap WETH->ETH as Bancor only deals in ETH | ||||||
|  |         if(_path[0] == address(WETH)) { | ||||||
|  |             //withdraw the sell amount of WETH for ETH | ||||||
|  |             WETH.withdraw(sellAmount); | ||||||
|  |             payableAmount = sellAmount; | ||||||
|  |             // set _path[0] to the ETH address if WETH is our buy token | ||||||
|  |             _path[0] = address(BANCORV3_ETH_ADDRESS); | ||||||
|  |         } else { | ||||||
|  |             // Grant the BancorV3 router an allowance to sell the first token. | ||||||
|  |             path[0].approveIfBelow(address(router), sellAmount); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // if we are buying WETH we need to swap to ETH and deposit into WETH after the swap | ||||||
|  |         if(_path[1] == address(WETH)){ | ||||||
|  |             _path[1] = address(BANCORV3_ETH_ADDRESS); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         uint256 amountOut = router.tradeBySourceAmount{value: payableAmount}( | ||||||
|  |             _path[0], | ||||||
|  |             _path[1], | ||||||
|  |              // Sell all tokens we hold. | ||||||
|  |             sellAmount, | ||||||
|  |              // Minimum buy amount. | ||||||
|  |             1, | ||||||
|  |             //deadline | ||||||
|  |             block.timestamp + 1, | ||||||
|  |             // address of the mixin | ||||||
|  |             address(this) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // if we want to return WETH deposit the ETH amount we sold | ||||||
|  |         if(buyToken == WETH){ | ||||||
|  |             WETH.deposit{value: amountOut}(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return amountOut; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,92 +0,0 @@ | |||||||
| // SPDX-License-Identifier: Apache-2.0 |  | ||||||
| /* |  | ||||||
|  |  | ||||||
|   Copyright 2020 ZeroEx Intl. |  | ||||||
|  |  | ||||||
|   Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|   you may not use this file except in compliance with the License. |  | ||||||
|   You may obtain a copy of the License at |  | ||||||
|  |  | ||||||
|     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  |  | ||||||
|   Unless required by applicable law or agreed to in writing, software |  | ||||||
|   distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|   See the License for the specific language governing permissions and |  | ||||||
|   limitations under the License. |  | ||||||
|  |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| pragma solidity ^0.6.5; |  | ||||||
| pragma experimental ABIEncoderV2; |  | ||||||
|  |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| interface ICoFiXRouter { |  | ||||||
|     // msg.value = fee |  | ||||||
|     function swapExactTokensForETH( |  | ||||||
|         address token, |  | ||||||
|         uint amountIn, |  | ||||||
|         uint amountOutMin, |  | ||||||
|         address to, |  | ||||||
|         address rewardTo, |  | ||||||
|         uint deadline |  | ||||||
|     ) external payable returns (uint _amountIn, uint _amountOut); |  | ||||||
|  |  | ||||||
|     // msg.value = amountIn + fee |  | ||||||
|     function swapExactETHForTokens( |  | ||||||
|         address token, |  | ||||||
|         uint amountIn, |  | ||||||
|         uint amountOutMin, |  | ||||||
|         address to, |  | ||||||
|         address rewardTo, |  | ||||||
|         uint deadline |  | ||||||
|     ) external payable returns (uint _amountIn, uint _amountOut); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| interface ICoFiXPair { |  | ||||||
|  |  | ||||||
|     function swapWithExact(address outToken, address to) |  | ||||||
|         external |  | ||||||
|         payable |  | ||||||
|         returns ( |  | ||||||
|             uint amountIn, |  | ||||||
|             uint amountOut, |  | ||||||
|             uint oracleFeeChange, |  | ||||||
|             uint256[4] memory tradeInfo |  | ||||||
|         ); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| contract MixinCoFiX { |  | ||||||
|  |  | ||||||
|     using LibERC20TokenV06 for IERC20TokenV06; |  | ||||||
|  |  | ||||||
|     function _tradeCoFiX( |  | ||||||
|         IERC20TokenV06 sellToken, |  | ||||||
|         IERC20TokenV06 buyToken, |  | ||||||
|         uint256 sellAmount, |  | ||||||
|         bytes memory bridgeData |  | ||||||
|     ) |  | ||||||
|         internal |  | ||||||
|         returns (uint256 boughtAmount) |  | ||||||
|     { |  | ||||||
|         (uint256 fee, ICoFiXPair pool) = abi.decode(bridgeData, (uint256, ICoFiXPair)); |  | ||||||
|         // Transfer tokens into the pool |  | ||||||
|         LibERC20TokenV06.compatTransfer( |  | ||||||
|             sellToken, |  | ||||||
|             address(pool), |  | ||||||
|             sellAmount |  | ||||||
|         ); |  | ||||||
|         // Call the swap exact with the tokens now in the pool |  | ||||||
|         // pay the NEST Oracle fee with ETH |  | ||||||
|         (/* In */, boughtAmount, , ) = pool.swapWithExact{value: fee}( |  | ||||||
|             address(buyToken), |  | ||||||
|             address(this) |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         return boughtAmount; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -0,0 +1,98 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  | import "../IBridgeAdapter.sol"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |     UniswapV2 | ||||||
|  | */ | ||||||
|  | interface IGmxRouter { | ||||||
|  |  | ||||||
|  |     // /// @dev Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path. | ||||||
|  |     // ///      The first element of path is the input token, the last is the output token, and any intermediate elements represent | ||||||
|  |     // ///      intermediate pairs to trade through (if, for example, a direct pair does not exist). | ||||||
|  |     // /// @param _path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. | ||||||
|  |     // /// @param _amountIn The amount of input tokens to send. | ||||||
|  |     // /// @param _minOut The minimum amount of output tokens that must be received for the transaction not to revert. | ||||||
|  |     // /// @param _reciever Recipient of the output tokens. | ||||||
|  |     function swap( | ||||||
|  |        address[] calldata _path, uint256 _amountIn, uint256 _minOut, address _receiver | ||||||
|  |     ) external; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinGMX { | ||||||
|  |  | ||||||
|  |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |  | ||||||
|  |     function _tradeGMX( | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |         address _router; | ||||||
|  |         address reader; | ||||||
|  |         address vault; | ||||||
|  |         address[] memory _path; | ||||||
|  |         IGmxRouter router; | ||||||
|  |         IERC20TokenV06[] memory path; | ||||||
|  |  | ||||||
|  |         { | ||||||
|  |             //decode the bridge data | ||||||
|  |             (_router, reader, vault, _path) = abi.decode(bridgeData, (address, address, address, address[])); | ||||||
|  |             // To get around `abi.decode()` not supporting interface array types. | ||||||
|  |             assembly { path := _path } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         require(path.length >= 2, "MixinGMX/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||||
|  |         require( | ||||||
|  |             path[path.length - 1] == buyToken, | ||||||
|  |             "MixinGMX/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         //connect to the GMX router | ||||||
|  |         router = IGmxRouter(_router); | ||||||
|  |  | ||||||
|  |         // Grant the GMX router an allowance to sell the first token. | ||||||
|  |         path[0].approveIfBelow(address(router), sellAmount); | ||||||
|  |  | ||||||
|  |         //track the balance to know how much we bought | ||||||
|  |         uint256 beforeBalance = buyToken.balanceOf(address(this)); | ||||||
|  |         router.swap( | ||||||
|  |             // Convert to `buyToken` along this path. | ||||||
|  |             _path, | ||||||
|  |              // Sell all tokens we hold. | ||||||
|  |             sellAmount, | ||||||
|  |              // Minimum buy amount. | ||||||
|  |             0, | ||||||
|  |             // Recipient is `this`. | ||||||
|  |             address(this) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         //calculate the difference in balance from preswap->postswap to find how many tokens out | ||||||
|  |         boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance); | ||||||
|  |  | ||||||
|  |         return boughtAmount; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,124 +0,0 @@ | |||||||
| // SPDX-License-Identifier: Apache-2.0 |  | ||||||
| /* |  | ||||||
|  |  | ||||||
|   Copyright 2020 ZeroEx Intl. |  | ||||||
|  |  | ||||||
|   Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|   you may not use this file except in compliance with the License. |  | ||||||
|   You may obtain a copy of the License at |  | ||||||
|  |  | ||||||
|     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  |  | ||||||
|   Unless required by applicable law or agreed to in writing, software |  | ||||||
|   distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|   See the License for the specific language governing permissions and |  | ||||||
|   limitations under the License. |  | ||||||
|  |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| pragma solidity ^0.6.5; |  | ||||||
| pragma experimental ABIEncoderV2; |  | ||||||
|  |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; |  | ||||||
| import "../IBridgeAdapter.sol"; |  | ||||||
|  |  | ||||||
| interface IKyberNetworkProxy { |  | ||||||
|  |  | ||||||
|     /// @dev Sells `sellTokenAddress` tokens for `buyTokenAddress` tokens |  | ||||||
|     /// using a hint for the reserve. |  | ||||||
|     /// @param sellToken Token to sell. |  | ||||||
|     /// @param sellAmount Amount of tokens to sell. |  | ||||||
|     /// @param buyToken Token to buy. |  | ||||||
|     /// @param recipientAddress Address to send bought tokens to. |  | ||||||
|     /// @param maxBuyTokenAmount A limit on the amount of tokens to buy. |  | ||||||
|     /// @param minConversionRate The minimal conversion rate. If actual rate |  | ||||||
|     ///        is lower, trade is canceled. |  | ||||||
|     /// @param walletId The wallet ID to send part of the fees |  | ||||||
|     /// @param hint The hint for the selective inclusion (or exclusion) of reserves |  | ||||||
|     /// @return boughtAmount Amount of tokens bought. |  | ||||||
|     function tradeWithHint( |  | ||||||
|         IERC20TokenV06 sellToken, |  | ||||||
|         uint256 sellAmount, |  | ||||||
|         IERC20TokenV06 buyToken, |  | ||||||
|         address payable recipientAddress, |  | ||||||
|         uint256 maxBuyTokenAmount, |  | ||||||
|         uint256 minConversionRate, |  | ||||||
|         address payable walletId, |  | ||||||
|         bytes calldata hint |  | ||||||
|     ) |  | ||||||
|         external |  | ||||||
|         payable |  | ||||||
|         returns (uint256 boughtAmount); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| contract MixinKyber { |  | ||||||
|  |  | ||||||
|     using LibERC20TokenV06 for IERC20TokenV06; |  | ||||||
|  |  | ||||||
|     /// @dev Address indicating the trade is using ETH |  | ||||||
|     IERC20TokenV06 private immutable KYBER_ETH_ADDRESS = |  | ||||||
|         IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); |  | ||||||
|     /// @dev Mainnet address of the WETH contract. |  | ||||||
|     IEtherTokenV06 private immutable WETH; |  | ||||||
|  |  | ||||||
|     constructor(IEtherTokenV06 weth) |  | ||||||
|         public |  | ||||||
|     { |  | ||||||
|         WETH = weth; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function _tradeKyber( |  | ||||||
|         IERC20TokenV06 sellToken, |  | ||||||
|         IERC20TokenV06 buyToken, |  | ||||||
|         uint256 sellAmount, |  | ||||||
|         bytes memory bridgeData |  | ||||||
|     ) |  | ||||||
|         internal |  | ||||||
|         returns (uint256 boughtAmount) |  | ||||||
|     { |  | ||||||
|         (IKyberNetworkProxy kyber, bytes memory hint) = |  | ||||||
|             abi.decode(bridgeData, (IKyberNetworkProxy, bytes)); |  | ||||||
|  |  | ||||||
|         uint256 payableAmount = 0; |  | ||||||
|         if (sellToken != WETH) { |  | ||||||
|             // If the input token is not WETH, grant an allowance to the exchange |  | ||||||
|             // to spend them. |  | ||||||
|             sellToken.approveIfBelow( |  | ||||||
|                 address(kyber), |  | ||||||
|                 sellAmount |  | ||||||
|             ); |  | ||||||
|         } else { |  | ||||||
|             // If the input token is WETH, unwrap it and attach it to the call. |  | ||||||
|             payableAmount = sellAmount; |  | ||||||
|             WETH.withdraw(payableAmount); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Try to sell all of this contract's input token balance through |  | ||||||
|         // `KyberNetworkProxy.trade()`. |  | ||||||
|         boughtAmount = kyber.tradeWithHint{ value: payableAmount }( |  | ||||||
|             // Input token. |  | ||||||
|             sellToken == WETH ? KYBER_ETH_ADDRESS : sellToken, |  | ||||||
|             // Sell amount. |  | ||||||
|             sellAmount, |  | ||||||
|             // Output token. |  | ||||||
|             buyToken == WETH ? KYBER_ETH_ADDRESS : buyToken, |  | ||||||
|             // Transfer to this contract |  | ||||||
|             address(uint160(address(this))), |  | ||||||
|             // Buy as much as possible. |  | ||||||
|             uint256(-1), |  | ||||||
|             // Lowest minimum conversion rate |  | ||||||
|             1, |  | ||||||
|             // No affiliate address. |  | ||||||
|             address(0), |  | ||||||
|             hint |  | ||||||
|         ); |  | ||||||
|         // If receving ETH, wrap it to WETH. |  | ||||||
|         if (buyToken == WETH) { |  | ||||||
|             WETH.deposit{ value: boughtAmount }(); |  | ||||||
|         } |  | ||||||
|         return boughtAmount; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -26,7 +26,7 @@ import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | |||||||
|  |  | ||||||
|  |  | ||||||
| /// @dev Minimal interface for minting StETH | /// @dev Minimal interface for minting StETH | ||||||
| interface ILido { | interface IStETH { | ||||||
|     /// @dev Adds eth to the pool |     /// @dev Adds eth to the pool | ||||||
|     /// @param _referral optional address for referrals |     /// @param _referral optional address for referrals | ||||||
|     /// @return StETH Amount of shares generated |     /// @return StETH Amount of shares generated | ||||||
| @@ -37,6 +37,33 @@ interface ILido { | |||||||
|     function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); |     function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// @dev Minimal interface for wrapping/unwrapping stETH. | ||||||
|  | interface IWstETH { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @notice Exchanges stETH to wstETH | ||||||
|  |      * @param _stETHAmount amount of stETH to wrap in exchange for wstETH | ||||||
|  |      * @dev Requirements: | ||||||
|  |      *  - `_stETHAmount` must be non-zero | ||||||
|  |      *  - msg.sender must approve at least `_stETHAmount` stETH to this | ||||||
|  |      *    contract. | ||||||
|  |      *  - msg.sender must have at least `_stETHAmount` of stETH. | ||||||
|  |      * User should first approve _stETHAmount to the WstETH contract | ||||||
|  |      * @return Amount of wstETH user receives after wrap | ||||||
|  |      */ | ||||||
|  |     function wrap(uint256 _stETHAmount) external returns (uint256); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @notice Exchanges wstETH to stETH | ||||||
|  |      * @param _wstETHAmount amount of wstETH to uwrap in exchange for stETH | ||||||
|  |      * @dev Requirements: | ||||||
|  |      *  - `_wstETHAmount` must be non-zero | ||||||
|  |      *  - msg.sender must have at least `_wstETHAmount` wstETH. | ||||||
|  |      * @return Amount of stETH user receives after unwrap | ||||||
|  |      */ | ||||||
|  |     function unwrap(uint256 _wstETHAmount) external returns (uint256); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| contract MixinLido { | contract MixinLido { | ||||||
|     using LibERC20TokenV06 for IERC20TokenV06; |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
| @@ -59,12 +86,43 @@ contract MixinLido { | |||||||
|         internal |         internal | ||||||
|         returns (uint256 boughtAmount) |         returns (uint256 boughtAmount) | ||||||
|     { |     { | ||||||
|         (ILido lido) = abi.decode(bridgeData, (ILido)); |         if (address(sellToken) == address(WETH)) { | ||||||
|         if (address(sellToken) == address(WETH) && address(buyToken) == address(lido)) { |             return _tradeStETH(buyToken, sellAmount, bridgeData); | ||||||
|  |         }  | ||||||
|  |  | ||||||
|  |         return _tradeWstETH(sellToken, buyToken, sellAmount, bridgeData); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _tradeStETH( | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) private returns (uint256 boughtAmount) { | ||||||
|  |         (IStETH stETH) = abi.decode(bridgeData, (IStETH)); | ||||||
|  |         if (address(buyToken) == address(stETH)) { | ||||||
|             WETH.withdraw(sellAmount); |             WETH.withdraw(sellAmount); | ||||||
|             boughtAmount = lido.getPooledEthByShares(lido.submit{ value: sellAmount}(address(0))); |             return stETH.getPooledEthByShares(stETH.submit{ value: sellAmount}(address(0))); | ||||||
|         } else { |  | ||||||
|             revert("MixinLido/UNSUPPORTED_TOKEN_PAIR"); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         revert("MixinLido/UNSUPPORTED_TOKEN_PAIR"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _tradeWstETH( | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |  | ||||||
|  |     ) private returns(uint256 boughtAmount){ | ||||||
|  |         (IEtherTokenV06 stETH, IWstETH wstETH) = abi.decode(bridgeData, (IEtherTokenV06, IWstETH)); | ||||||
|  |         if (address(sellToken) == address(stETH) && address(buyToken) == address(wstETH) ) { | ||||||
|  |             sellToken.approveIfBelow(address(wstETH), sellAmount); | ||||||
|  |             return wstETH.wrap(sellAmount); | ||||||
|  |         } | ||||||
|  |         if (address(sellToken) == address(wstETH) && address(buyToken) == address(stETH) ) { | ||||||
|  |             return wstETH.unwrap(sellAmount); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         revert("MixinLido/UNSUPPORTED_TOKEN_PAIR"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,76 +0,0 @@ | |||||||
| // SPDX-License-Identifier: Apache-2.0 |  | ||||||
| /* |  | ||||||
|  |  | ||||||
|   Copyright 2020 ZeroEx Intl. |  | ||||||
|  |  | ||||||
|   Licensed under the Apache License, Version 2.0 (the "License"); |  | ||||||
|   you may not use this file except in compliance with the License. |  | ||||||
|   You may obtain a copy of the License at |  | ||||||
|  |  | ||||||
|     http://www.apache.org/licenses/LICENSE-2.0 |  | ||||||
|  |  | ||||||
|   Unless required by applicable law or agreed to in writing, software |  | ||||||
|   distributed under the License is distributed on an "AS IS" BASIS, |  | ||||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |  | ||||||
|   See the License for the specific language governing permissions and |  | ||||||
|   limitations under the License. |  | ||||||
|  |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| pragma solidity ^0.6.5; |  | ||||||
| pragma experimental ABIEncoderV2; |  | ||||||
|  |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; |  | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; |  | ||||||
| import "../IBridgeAdapter.sol"; |  | ||||||
|  |  | ||||||
| interface IOasis { |  | ||||||
|  |  | ||||||
|     /// @dev Sell `sellAmount` of `sellToken` token and receive `buyToken` token. |  | ||||||
|     /// @param sellToken The token being sold. |  | ||||||
|     /// @param sellAmount The amount of `sellToken` token being sold. |  | ||||||
|     /// @param buyToken The token being bought. |  | ||||||
|     /// @param minBoughtAmount Minimum amount of `buyToken` token to buy. |  | ||||||
|     /// @return boughtAmount Amount of `buyToken` bought. |  | ||||||
|     function sellAllAmount( |  | ||||||
|         IERC20TokenV06 sellToken, |  | ||||||
|         uint256 sellAmount, |  | ||||||
|         IERC20TokenV06 buyToken, |  | ||||||
|         uint256 minBoughtAmount |  | ||||||
|     ) |  | ||||||
|         external |  | ||||||
|         returns (uint256 boughtAmount); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| contract MixinOasis { |  | ||||||
|  |  | ||||||
|     using LibERC20TokenV06 for IERC20TokenV06; |  | ||||||
|  |  | ||||||
|     function _tradeOasis( |  | ||||||
|         IERC20TokenV06 sellToken, |  | ||||||
|         IERC20TokenV06 buyToken, |  | ||||||
|         uint256 sellAmount, |  | ||||||
|         bytes memory bridgeData |  | ||||||
|     ) |  | ||||||
|         internal |  | ||||||
|         returns (uint256 boughtAmount) |  | ||||||
|     { |  | ||||||
|  |  | ||||||
|         (IOasis oasis) = abi.decode(bridgeData, (IOasis)); |  | ||||||
|  |  | ||||||
|         // Grant an allowance to the exchange to spend `sellToken` token. |  | ||||||
|         sellToken.approveIfBelow( |  | ||||||
|             address(oasis), |  | ||||||
|             sellAmount |  | ||||||
|         ); |  | ||||||
|         // Try to sell all of this contract's `sellToken` token balance. |  | ||||||
|         boughtAmount = oasis.sellAllAmount( |  | ||||||
|             sellToken, |  | ||||||
|             sellAmount, |  | ||||||
|             buyToken, |  | ||||||
|             // min fill amount |  | ||||||
|             1 |  | ||||||
|         ); |  | ||||||
|         return boughtAmount; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -0,0 +1,98 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IPlatypusRouter { | ||||||
|  |  | ||||||
|  |     function swapTokensForTokens( | ||||||
|  |         address[] calldata tokenPath, | ||||||
|  |         address[] calldata poolPath, | ||||||
|  |         uint256 fromAmount, | ||||||
|  |         uint256 minimumToAmount, | ||||||
|  |         address to, | ||||||
|  |         uint256 deadline | ||||||
|  |     ) external returns (uint256 amountOut, uint256 haircut); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinPlatypus { | ||||||
|  |  | ||||||
|  |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |  | ||||||
|  |     function _tradePlatypus( | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |         IPlatypusRouter router; | ||||||
|  |         address _router; | ||||||
|  |         address[] memory _pool; | ||||||
|  |         IERC20TokenV06[] memory path; | ||||||
|  |         address[] memory _path; | ||||||
|  |  | ||||||
|  |         { | ||||||
|  |             (_router, _pool, _path) = abi.decode(bridgeData, (address, address[], address[])); | ||||||
|  |  | ||||||
|  |             // To get around `abi.decode()` not supporting interface array types. | ||||||
|  |             assembly { path := _path } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         //connect to the ptp router | ||||||
|  |         router = IPlatypusRouter(_router); | ||||||
|  |  | ||||||
|  |         require(path.length >= 2, "MixinPlatypus/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||||
|  |         require( | ||||||
|  |             path[path.length - 1] == buyToken, | ||||||
|  |             "MixinPlatypus/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN" | ||||||
|  |         ); | ||||||
|  |         // Grant the Platypus router an allowance to sell the first token. | ||||||
|  |         path[0].approveIfBelow(address(router), sellAmount); | ||||||
|  |  | ||||||
|  |         //keep track of the previous balance to confirm amount out | ||||||
|  |         uint256 beforeBalance = buyToken.balanceOf(address(this)); | ||||||
|  |  | ||||||
|  |         router.swapTokensForTokens( | ||||||
|  |             // Convert to `buyToken` along this path. | ||||||
|  |             _path, | ||||||
|  |             // pool to swap on | ||||||
|  |             _pool, | ||||||
|  |              // Sell all tokens we hold. | ||||||
|  |             sellAmount, | ||||||
|  |              // Minimum buy amount. | ||||||
|  |             0, | ||||||
|  |             // Recipient is `this`. | ||||||
|  |             address(this), | ||||||
|  |  | ||||||
|  |             block.timestamp + 1 | ||||||
|  |         ); | ||||||
|  |         //calculate the buy amount from the tokens we recieved | ||||||
|  |         boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance); | ||||||
|  |         return boughtAmount; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,99 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | interface ISynthetix { | ||||||
|  |     // Ethereum Mainnet | ||||||
|  |     function exchangeAtomically( | ||||||
|  |         bytes32 sourceCurrencyKey, | ||||||
|  |         uint256 sourceAmount, | ||||||
|  |         bytes32 destinationCurrencyKey, | ||||||
|  |         bytes32 trackingCode, | ||||||
|  |         uint256 minAmount | ||||||
|  |     ) external returns (uint256 amountReceived); | ||||||
|  |  | ||||||
|  |     // Optimism | ||||||
|  |     function exchangeWithTracking( | ||||||
|  |         bytes32 sourceCurrencyKey, | ||||||
|  |         uint256 sourceAmount, | ||||||
|  |         bytes32 destinationCurrencyKey, | ||||||
|  |         address rewardAddress, | ||||||
|  |         bytes32 trackingCode | ||||||
|  |     ) external returns (uint256 amountReceived); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinSynthetix { | ||||||
|  |     address private constant rewardAddress = | ||||||
|  |         0x5C80239D97E1eB216b5c3D8fBa5DE5Be5d38e4C9; | ||||||
|  |     bytes32 constant trackingCode = | ||||||
|  |         0x3058000000000000000000000000000000000000000000000000000000000000; | ||||||
|  |  | ||||||
|  |     function _tradeSynthetix(uint256 sellAmount, bytes memory bridgeData) | ||||||
|  |         public | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |         ( | ||||||
|  |             ISynthetix synthetix, | ||||||
|  |             bytes32 sourceCurrencyKey, | ||||||
|  |             bytes32 destinationCurrencyKey | ||||||
|  |         ) = abi.decode( | ||||||
|  |                 bridgeData, | ||||||
|  |                 (ISynthetix, bytes32, bytes32) | ||||||
|  |             ); | ||||||
|  |  | ||||||
|  |         boughtAmount = exchange( | ||||||
|  |             synthetix, | ||||||
|  |             sourceCurrencyKey, | ||||||
|  |             destinationCurrencyKey, | ||||||
|  |             sellAmount | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function exchange( | ||||||
|  |         ISynthetix synthetix, | ||||||
|  |         bytes32 sourceCurrencyKey, | ||||||
|  |         bytes32 destinationCurrencyKey, | ||||||
|  |         uint256 sellAmount | ||||||
|  |     ) internal returns (uint256 boughtAmount) { | ||||||
|  |         uint256 chainId; | ||||||
|  |         assembly { | ||||||
|  |             chainId := chainid() | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (chainId == 1) { | ||||||
|  |             boughtAmount = synthetix.exchangeAtomically( | ||||||
|  |                 sourceCurrencyKey, | ||||||
|  |                 sellAmount, | ||||||
|  |                 destinationCurrencyKey, | ||||||
|  |                 trackingCode, | ||||||
|  |                 0 | ||||||
|  |             ); | ||||||
|  |         } else { | ||||||
|  |             boughtAmount = synthetix.exchangeWithTracking( | ||||||
|  |                 sourceCurrencyKey, | ||||||
|  |                 sellAmount, | ||||||
|  |                 destinationCurrencyKey, | ||||||
|  |                 rewardAddress, | ||||||
|  |                 trackingCode | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,64 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  |  | ||||||
|  | interface IVelodromeRouter { | ||||||
|  |     function swapExactTokensForTokensSimple( | ||||||
|  |         uint256 amountIn, | ||||||
|  |         uint256 amountOutMin, | ||||||
|  |         address tokenFrom, | ||||||
|  |         address tokenTo, | ||||||
|  |         bool stable, | ||||||
|  |         address to, | ||||||
|  |         uint256 deadline | ||||||
|  |     ) external returns (uint256[] memory amounts);  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinVelodrome { | ||||||
|  |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
|  |  | ||||||
|  |     function _tradeVelodrome( | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) | ||||||
|  |         internal | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         (IVelodromeRouter router, bool stable) = abi.decode(bridgeData, (IVelodromeRouter, bool)); | ||||||
|  |         sellToken.approveIfBelow(address(router), sellAmount); | ||||||
|  |  | ||||||
|  |         boughtAmount = router.swapExactTokensForTokensSimple( | ||||||
|  |             sellAmount, | ||||||
|  |             0,  | ||||||
|  |             address(sellToken), | ||||||
|  |             address(buyToken), | ||||||
|  |             stable, | ||||||
|  |             address(this), | ||||||
|  |             block.timestamp + 1 | ||||||
|  |         )[1]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,136 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | ||||||
|  | import "../IBridgeAdapter.sol"; | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  |  | ||||||
|  | /// @dev WooFI pool interface. | ||||||
|  | interface IWooPP { | ||||||
|  |     function quoteToken() external view returns (address); | ||||||
|  |  | ||||||
|  |     function sellBase( | ||||||
|  |         address baseToken, | ||||||
|  |         uint256 baseAmount, | ||||||
|  |         uint256 minQuoteAmount, | ||||||
|  |         address to, | ||||||
|  |         address rebateTo | ||||||
|  |     ) external returns (uint256 quoteAmount); | ||||||
|  |  | ||||||
|  |     function sellQuote( | ||||||
|  |         address baseToken, | ||||||
|  |         uint256 quoteAmount, | ||||||
|  |         uint256 minBaseAmount, | ||||||
|  |         address to, | ||||||
|  |         address rebateTo | ||||||
|  |     ) external returns (uint256 baseAmount); | ||||||
|  |  | ||||||
|  |     /// @dev Query the amount for selling the base token amount. | ||||||
|  |     /// @param baseToken the base token to sell | ||||||
|  |     /// @param baseAmount the amount to sell | ||||||
|  |     /// @return quoteAmount the swapped quote amount | ||||||
|  |     function querySellBase( | ||||||
|  |         address baseToken,  | ||||||
|  |         uint256 baseAmount | ||||||
|  |     ) external view returns (uint256 quoteAmount); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract MixinWOOFi{ | ||||||
|  |  | ||||||
|  |     using LibERC20TokenV06 for IERC20TokenV06; | ||||||
|  |     using LibERC20TokenV06 for IEtherTokenV06; | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |  | ||||||
|  |     address constant rebateAddress = 0xBfdcBB4C05843163F491C24f9c0019c510786304; | ||||||
|  |  | ||||||
|  |     // /// @dev Swaps an exact amount of input tokens for as many output tokens as possible. | ||||||
|  |     // /// @param _amountIn Amount of input tokens to send | ||||||
|  |     // /// @param _minAmountOut The minimum amount of output tokens that must be received for the transaction not to revert. | ||||||
|  |     // /// @param _tokenIn Input token | ||||||
|  |     // /// @param _tokenOut Output token | ||||||
|  |     // /// @param _to recipient of tokens | ||||||
|  |     // /// @param pool WOOFi pool where the swap will happen | ||||||
|  |     function _tradeWOOFi( | ||||||
|  |         IERC20TokenV06 sellToken, | ||||||
|  |         IERC20TokenV06 buyToken, | ||||||
|  |         uint256 sellAmount, | ||||||
|  |         bytes memory bridgeData | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |         returns (uint256 boughtAmount) | ||||||
|  |     { | ||||||
|  |         (IWooPP _pool) = abi.decode(bridgeData, (IWooPP)); | ||||||
|  |         uint256 beforeBalance = buyToken.balanceOf(address(this)); | ||||||
|  |  | ||||||
|  |         sellToken.approveIfBelow(address(_pool), sellAmount); | ||||||
|  |          | ||||||
|  |         _swap( | ||||||
|  |             sellAmount, | ||||||
|  |             address(sellToken), | ||||||
|  |             address(buyToken), | ||||||
|  |             _pool | ||||||
|  |         ); | ||||||
|  |         boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function _swap( | ||||||
|  |         uint _amountIn,  | ||||||
|  |         address _tokenIn,  | ||||||
|  |         address _tokenOut,  | ||||||
|  |         IWooPP pool | ||||||
|  |     ) internal { | ||||||
|  |         address quoteToken = pool.quoteToken(); | ||||||
|  |         if (_tokenIn == quoteToken) { | ||||||
|  |             pool.sellQuote( | ||||||
|  |                 _tokenOut, | ||||||
|  |                 _amountIn, | ||||||
|  |                 1, | ||||||
|  |                 address(this), | ||||||
|  |                 rebateAddress | ||||||
|  |             ); | ||||||
|  |         } else if (_tokenOut == quoteToken) { | ||||||
|  |             pool.sellBase( | ||||||
|  |                 _tokenIn,  | ||||||
|  |                 _amountIn,  | ||||||
|  |                 1,  | ||||||
|  |                 address(this),  | ||||||
|  |                 rebateAddress | ||||||
|  |             ); | ||||||
|  |         } else {           | ||||||
|  |             uint256 quoteAmount = pool.sellBase( | ||||||
|  |                 _tokenIn,  | ||||||
|  |                 _amountIn,  | ||||||
|  |                 0,  | ||||||
|  |                 address(this),  | ||||||
|  |                 rebateAddress | ||||||
|  |             ); | ||||||
|  |             IERC20TokenV06(pool.quoteToken()).approveIfBelow(address(pool), quoteAmount); | ||||||
|  |             pool.sellQuote( | ||||||
|  |                 _tokenOut,  | ||||||
|  |                 quoteAmount,  | ||||||
|  |                 1,  | ||||||
|  |                 address(this),  | ||||||
|  |                 rebateAddress | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										151
									
								
								contracts/zero-ex/contracts/src/vendor/IERC1155Token.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								contracts/zero-ex/contracts/src/vendor/IERC1155Token.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2022 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IERC1155Token { | ||||||
|  |  | ||||||
|  |     /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, | ||||||
|  |     ///      including zero value transfers as well as minting or burning. | ||||||
|  |     /// Operator will always be msg.sender. | ||||||
|  |     /// Either event from address `0x0` signifies a minting operation. | ||||||
|  |     /// An event to address `0x0` signifies a burning or melting operation. | ||||||
|  |     /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may | ||||||
|  |     /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID. | ||||||
|  |     /// To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event | ||||||
|  |     /// from `0x0` to `0x0`, with the token creator as `_operator`. | ||||||
|  |     event TransferSingle( | ||||||
|  |         address indexed operator, | ||||||
|  |         address indexed from, | ||||||
|  |         address indexed to, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 value | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, | ||||||
|  |     ///      including zero value transfers as well as minting or burning. | ||||||
|  |     ///Operator will always be msg.sender. | ||||||
|  |     /// Either event from address `0x0` signifies a minting operation. | ||||||
|  |     /// An event to address `0x0` signifies a burning or melting operation. | ||||||
|  |     /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may | ||||||
|  |     /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID. | ||||||
|  |     /// To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event | ||||||
|  |     /// from `0x0` to `0x0`, with the token creator as `_operator`. | ||||||
|  |     event TransferBatch( | ||||||
|  |         address indexed operator, | ||||||
|  |         address indexed from, | ||||||
|  |         address indexed to, | ||||||
|  |         uint256[] ids, | ||||||
|  |         uint256[] values | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev MUST emit when an approval is updated. | ||||||
|  |     event ApprovalForAll( | ||||||
|  |         address indexed owner, | ||||||
|  |         address indexed operator, | ||||||
|  |         bool approved | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev MUST emit when the URI is updated for a token ID. | ||||||
|  |     /// URIs are defined in RFC 3986. | ||||||
|  |     /// The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema". | ||||||
|  |     event URI( | ||||||
|  |         string value, | ||||||
|  |         uint256 indexed id | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @notice Transfers value amount of an _id from the _from address to the _to address specified. | ||||||
|  |     /// @dev MUST emit TransferSingle event on success. | ||||||
|  |     /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll). | ||||||
|  |     /// MUST throw if `_to` is the zero address. | ||||||
|  |     /// MUST throw if balance of sender for token `_id` is lower than the `_value` sent. | ||||||
|  |     /// MUST throw on any other error. | ||||||
|  |     /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). | ||||||
|  |     /// If so, it MUST call `onERC1155Received` on `_to` and revert if the return value | ||||||
|  |     /// is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`. | ||||||
|  |     /// @param from    Source address | ||||||
|  |     /// @param to      Target address | ||||||
|  |     /// @param id      ID of the token type | ||||||
|  |     /// @param value   Transfer amount | ||||||
|  |     /// @param data    Additional data with no specified format, sent in call to `_to` | ||||||
|  |     function safeTransferFrom( | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 value, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call). | ||||||
|  |     /// @dev MUST emit TransferBatch event on success. | ||||||
|  |     /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll). | ||||||
|  |     /// MUST throw if `_to` is the zero address. | ||||||
|  |     /// MUST throw if length of `_ids` is not the same as length of `_values`. | ||||||
|  |     ///  MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent. | ||||||
|  |     /// MUST throw on any other error. | ||||||
|  |     /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). | ||||||
|  |     /// If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value | ||||||
|  |     /// is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`. | ||||||
|  |     /// @param from    Source addresses | ||||||
|  |     /// @param to      Target addresses | ||||||
|  |     /// @param ids     IDs of each token type | ||||||
|  |     /// @param values  Transfer amounts per token type | ||||||
|  |     /// @param data    Additional data with no specified format, sent in call to `_to` | ||||||
|  |     function safeBatchTransferFrom( | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256[] calldata ids, | ||||||
|  |         uint256[] calldata values, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. | ||||||
|  |     /// @dev MUST emit the ApprovalForAll event on success. | ||||||
|  |     /// @param operator  Address to add to the set of authorized operators | ||||||
|  |     /// @param approved  True if the operator is approved, false to revoke approval | ||||||
|  |     function setApprovalForAll(address operator, bool approved) external; | ||||||
|  |  | ||||||
|  |     /// @notice Queries the approval status of an operator for a given owner. | ||||||
|  |     /// @param owner        The owner of the Tokens | ||||||
|  |     /// @param operator     Address of authorized operator | ||||||
|  |     /// @return isApproved  True if the operator is approved, false if not | ||||||
|  |     function isApprovedForAll(address owner, address operator) external view returns (bool isApproved); | ||||||
|  |  | ||||||
|  |     /// @notice Get the balance of an account's Tokens. | ||||||
|  |     /// @param owner     The address of the token holder | ||||||
|  |     /// @param id        ID of the Token | ||||||
|  |     /// @return balance  The _owner's balance of the Token type requested | ||||||
|  |     function balanceOf(address owner, uint256 id) external view returns (uint256 balance); | ||||||
|  |  | ||||||
|  |     /// @notice Get the balance of multiple account/token pairs | ||||||
|  |     /// @param owners      The addresses of the token holders | ||||||
|  |     /// @param ids         ID of the Tokens | ||||||
|  |     /// @return balances_  The _owner's balance of the Token types requested | ||||||
|  |     function balanceOfBatch( | ||||||
|  |         address[] calldata owners, | ||||||
|  |         uint256[] calldata ids | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (uint256[] memory balances_); | ||||||
|  | } | ||||||
							
								
								
									
										159
									
								
								contracts/zero-ex/contracts/src/vendor/IERC721Token.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								contracts/zero-ex/contracts/src/vendor/IERC721Token.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IERC721Token { | ||||||
|  |  | ||||||
|  |     /// @dev This emits when ownership of any NFT changes by any mechanism. | ||||||
|  |     ///      This event emits when NFTs are created (`from` == 0) and destroyed | ||||||
|  |     ///      (`to` == 0). Exception: during contract creation, any number of NFTs | ||||||
|  |     ///      may be created and assigned without emitting Transfer. At the time of | ||||||
|  |     ///      any transfer, the approved address for that NFT (if any) is reset to none. | ||||||
|  |     event Transfer( | ||||||
|  |         address indexed _from, | ||||||
|  |         address indexed _to, | ||||||
|  |         uint256 indexed _tokenId | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev This emits when the approved address for an NFT is changed or | ||||||
|  |     ///      reaffirmed. The zero address indicates there is no approved address. | ||||||
|  |     ///      When a Transfer event emits, this also indicates that the approved | ||||||
|  |     ///      address for that NFT (if any) is reset to none. | ||||||
|  |     event Approval( | ||||||
|  |         address indexed _owner, | ||||||
|  |         address indexed _approved, | ||||||
|  |         uint256 indexed _tokenId | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev This emits when an operator is enabled or disabled for an owner. | ||||||
|  |     ///      The operator can manage all NFTs of the owner. | ||||||
|  |     event ApprovalForAll( | ||||||
|  |         address indexed _owner, | ||||||
|  |         address indexed _operator, | ||||||
|  |         bool _approved | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @notice Transfers the ownership of an NFT from one address to another address | ||||||
|  |     /// @dev Throws unless `msg.sender` is the current owner, an authorized | ||||||
|  |     ///      perator, or the approved address for this NFT. Throws if `_from` is | ||||||
|  |     ///      not the current owner. Throws if `_to` is the zero address. Throws if | ||||||
|  |     ///      `_tokenId` is not a valid NFT. When transfer is complete, this function | ||||||
|  |     ///      checks if `_to` is a smart contract (code size > 0). If so, it calls | ||||||
|  |     ///      `onERC721Received` on `_to` and throws if the return value is not | ||||||
|  |     ///      `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. | ||||||
|  |     /// @param _from The current owner of the NFT | ||||||
|  |     /// @param _to The new owner | ||||||
|  |     /// @param _tokenId The NFT to transfer | ||||||
|  |     /// @param _data Additional data with no specified format, sent in call to `_to` | ||||||
|  |     function safeTransferFrom( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId, | ||||||
|  |         bytes calldata _data | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Transfers the ownership of an NFT from one address to another address | ||||||
|  |     /// @dev This works identically to the other function with an extra data parameter, | ||||||
|  |     ///      except this function just sets data to "". | ||||||
|  |     /// @param _from The current owner of the NFT | ||||||
|  |     /// @param _to The new owner | ||||||
|  |     /// @param _tokenId The NFT to transfer | ||||||
|  |     function safeTransferFrom( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Change or reaffirm the approved address for an NFT | ||||||
|  |     /// @dev The zero address indicates there is no approved address. | ||||||
|  |     ///      Throws unless `msg.sender` is the current NFT owner, or an authorized | ||||||
|  |     ///      operator of the current owner. | ||||||
|  |     /// @param _approved The new approved NFT controller | ||||||
|  |     /// @param _tokenId The NFT to approve | ||||||
|  |     function approve(address _approved, uint256 _tokenId) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Enable or disable approval for a third party ("operator") to manage | ||||||
|  |     ///         all of `msg.sender`'s assets | ||||||
|  |     /// @dev Emits the ApprovalForAll event. The contract MUST allow | ||||||
|  |     ///      multiple operators per owner. | ||||||
|  |     /// @param _operator Address to add to the set of authorized operators | ||||||
|  |     /// @param _approved True if the operator is approved, false to revoke approval | ||||||
|  |     function setApprovalForAll(address _operator, bool _approved) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Count all NFTs assigned to an owner | ||||||
|  |     /// @dev NFTs assigned to the zero address are considered invalid, and this | ||||||
|  |     ///      function throws for queries about the zero address. | ||||||
|  |     /// @param _owner An address for whom to query the balance | ||||||
|  |     /// @return The number of NFTs owned by `_owner`, possibly zero | ||||||
|  |     function balanceOf(address _owner) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (uint256); | ||||||
|  |  | ||||||
|  |     /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE | ||||||
|  |     ///         TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE | ||||||
|  |     ///         THEY MAY BE PERMANENTLY LOST | ||||||
|  |     /// @dev Throws unless `msg.sender` is the current owner, an authorized | ||||||
|  |     ///      operator, or the approved address for this NFT. Throws if `_from` is | ||||||
|  |     ///      not the current owner. Throws if `_to` is the zero address. Throws if | ||||||
|  |     ///      `_tokenId` is not a valid NFT. | ||||||
|  |     /// @param _from The current owner of the NFT | ||||||
|  |     /// @param _to The new owner | ||||||
|  |     /// @param _tokenId The NFT to transfer | ||||||
|  |     function transferFrom( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId | ||||||
|  |     ) | ||||||
|  |         external; | ||||||
|  |  | ||||||
|  |     /// @notice Find the owner of an NFT | ||||||
|  |     /// @dev NFTs assigned to zero address are considered invalid, and queries | ||||||
|  |     ///      about them do throw. | ||||||
|  |     /// @param _tokenId The identifier for an NFT | ||||||
|  |     /// @return The address of the owner of the NFT | ||||||
|  |     function ownerOf(uint256 _tokenId) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (address); | ||||||
|  |  | ||||||
|  |     /// @notice Get the approved address for a single NFT | ||||||
|  |     /// @dev Throws if `_tokenId` is not a valid NFT. | ||||||
|  |     /// @param _tokenId The NFT to find the approved address for | ||||||
|  |     /// @return The approved address for this NFT, or the zero address if there is none | ||||||
|  |     function getApproved(uint256 _tokenId) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (address); | ||||||
|  |  | ||||||
|  |     /// @notice Query if an address is an authorized operator for another address | ||||||
|  |     /// @param _owner The address that owns the NFTs | ||||||
|  |     /// @param _operator The address that acts on behalf of the owner | ||||||
|  |     /// @return True if `_operator` is an approved operator for `_owner`, false otherwise | ||||||
|  |     function isApprovedForAll(address _owner, address _operator) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (bool); | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								contracts/zero-ex/contracts/src/vendor/IFeeRecipient.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								contracts/zero-ex/contracts/src/vendor/IFeeRecipient.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IFeeRecipient { | ||||||
|  |  | ||||||
|  |     /// @dev A callback function invoked in the ERC721Feature for each ERC721 | ||||||
|  |     ///      order fee that get paid. Integrators can make use of this callback | ||||||
|  |     ///      to implement arbitrary fee-handling logic, e.g. splitting the fee | ||||||
|  |     ///      between multiple parties. | ||||||
|  |     /// @param tokenAddress The address of the token in which the received fee is | ||||||
|  |     ///        denominated. `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` indicates | ||||||
|  |     ///        that the fee was paid in the native token (e.g. ETH). | ||||||
|  |     /// @param amount The amount of the given token received. | ||||||
|  |     /// @param feeData Arbitrary data encoded in the `Fee` used by this callback. | ||||||
|  |     /// @return success The selector of this function (0x0190805e), | ||||||
|  |     ///         indicating that the callback succeeded. | ||||||
|  |     function receiveZeroExFeeCallback( | ||||||
|  |         address tokenAddress, | ||||||
|  |         uint256 amount, | ||||||
|  |         bytes calldata feeData | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success); | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								contracts/zero-ex/contracts/src/vendor/IPropertyValidator.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								contracts/zero-ex/contracts/src/vendor/IPropertyValidator.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IPropertyValidator { | ||||||
|  |  | ||||||
|  |     /// @dev Checks that the given ERC721/ERC1155 asset satisfies the properties encoded in `propertyData`. | ||||||
|  |     ///      Should revert if the asset does not satisfy the specified properties. | ||||||
|  |     /// @param tokenAddress The ERC721/ERC1155 token contract address. | ||||||
|  |     /// @param tokenId The ERC721/ERC1155 tokenId of the asset to check. | ||||||
|  |     /// @param propertyData Encoded properties or auxiliary data needed to perform the check. | ||||||
|  |     function validateProperty( | ||||||
|  |         address tokenAddress, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         bytes calldata propertyData | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         view; | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								contracts/zero-ex/contracts/src/vendor/ITakerCallback.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								contracts/zero-ex/contracts/src/vendor/ITakerCallback.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface ITakerCallback { | ||||||
|  |  | ||||||
|  |     /// @dev A taker callback function invoked in ERC721OrdersFeature and | ||||||
|  |     ///      ERC1155OrdersFeature between the maker -> taker transfer and | ||||||
|  |     ///      the taker -> maker transfer. | ||||||
|  |     /// @param orderHash The hash of the order being filled when this | ||||||
|  |     ///        callback is invoked. | ||||||
|  |     /// @param callbackData Arbitrary data used by this callback. | ||||||
|  |     /// @return success The selector of this function, | ||||||
|  |     ///         indicating that the callback succeeded. | ||||||
|  |     function zeroExTakerCallback( | ||||||
|  |         bytes32 orderHash, | ||||||
|  |         bytes calldata callbackData | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success); | ||||||
|  | } | ||||||
							
								
								
									
										55
									
								
								contracts/zero-ex/contracts/test/TestFeeRecipient.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								contracts/zero-ex/contracts/test/TestFeeRecipient.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | contract TestFeeRecipient { | ||||||
|  |     bytes4 constant private SUCCESS = this.receiveZeroExFeeCallback.selector; | ||||||
|  |     bytes4 constant private FAILURE = 0xdeadbeef; | ||||||
|  |  | ||||||
|  |     uint256 constant private TRIGGER_REVERT = 333; | ||||||
|  |     uint256 constant private TRIGGER_FAILURE = 666; | ||||||
|  |  | ||||||
|  |     event FeeReceived( | ||||||
|  |         address tokenAddress, | ||||||
|  |         uint256 amount | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     receive() external payable {} | ||||||
|  |  | ||||||
|  |     function receiveZeroExFeeCallback( | ||||||
|  |         address tokenAddress, | ||||||
|  |         uint256 amount, | ||||||
|  |         bytes calldata /* feeData */ | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (bytes4 success) | ||||||
|  |     { | ||||||
|  |         emit FeeReceived(tokenAddress, amount); | ||||||
|  |         if (amount == TRIGGER_REVERT) { | ||||||
|  |             revert("TestFeeRecipient::receiveZeroExFeeCallback/REVERT"); | ||||||
|  |         } else if (amount == TRIGGER_FAILURE) { | ||||||
|  |             return FAILURE; | ||||||
|  |         } else { | ||||||
|  |             return SUCCESS; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -22,7 +22,7 @@ pragma experimental ABIEncoderV2; | |||||||
|  |  | ||||||
| import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; | import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; | ||||||
| import "../src/vendor/v3/IERC20Bridge.sol"; | import "../src/vendor/v3/IERC20Bridge.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "./tokens/TestMintableERC20Token.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
| contract TestFillQuoteTransformerBridge { | contract TestFillQuoteTransformerBridge { | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ pragma experimental ABIEncoderV2; | |||||||
| import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol"; | import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol"; | ||||||
| import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; | import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; | ||||||
| import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "./tokens/TestMintableERC20Token.sol"; | ||||||
| import "../src/features/libs/LibNativeOrder.sol"; | import "../src/features/libs/LibNativeOrder.sol"; | ||||||
| import "../src/features/libs/LibSignature.sol"; | import "../src/features/libs/LibSignature.sol"; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ pragma solidity ^0.6.5; | |||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
| import "../src/transformers/IERC20Transformer.sol"; | import "../src/transformers/IERC20Transformer.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "./tokens/TestMintableERC20Token.sol"; | ||||||
| import "./TestTransformerHost.sol"; | import "./TestTransformerHost.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ pragma experimental ABIEncoderV2; | |||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
| import "../src/transformers/IERC20Transformer.sol"; | import "../src/transformers/IERC20Transformer.sol"; | ||||||
| import "../src/transformers/LibERC20Transformer.sol"; | import "../src/transformers/LibERC20Transformer.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "./tokens/TestMintableERC20Token.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
| contract TestMintTokenERC20Transformer is | contract TestMintTokenERC20Transformer is | ||||||
|   | |||||||
							
								
								
									
										93
									
								
								contracts/zero-ex/contracts/test/TestNFTOrderPresigner.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								contracts/zero-ex/contracts/test/TestNFTOrderPresigner.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2021 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
|  | import "../src/IZeroEx.sol"; | ||||||
|  | import "../src/vendor/IERC1155Token.sol"; | ||||||
|  | import "../src/vendor/IERC721Token.sol"; | ||||||
|  | import "../src/features/libs/LibNFTOrder.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | contract TestNFTOrderPresigner { | ||||||
|  |     IZeroEx private immutable zeroEx; | ||||||
|  |  | ||||||
|  |     constructor(IZeroEx _zeroEx) | ||||||
|  |         public | ||||||
|  |     { | ||||||
|  |         zeroEx = _zeroEx; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function onERC1155Received( | ||||||
|  |         address operator, | ||||||
|  |         address from, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 value, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns(bytes4 success) | ||||||
|  |     { | ||||||
|  |         return 0xf23a6e61; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function approveERC721(IERC721Token token) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         token.setApprovalForAll(address(zeroEx), true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function approveERC1155(IERC1155Token token) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         token.setApprovalForAll(address(zeroEx), true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function approveERC20(IERC20TokenV06 token) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         token.approve(address(zeroEx), uint256(-1)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function preSignERC721Order(LibNFTOrder.ERC721Order calldata order) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         zeroEx.preSignERC721Order(order); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function preSignERC1155Order(LibNFTOrder.ERC1155Order calldata order) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         zeroEx.preSignERC1155Order(order); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function cancelERC721Order(uint256 orderNonce) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         zeroEx.cancelERC721Order(orderNonce); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function cancelERC1155Order(uint256 orderNonce) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         zeroEx.cancelERC1155Order(orderNonce); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -17,29 +17,23 @@ | |||||||
| 
 | 
 | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| pragma solidity ^0.6; | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| interface ISmoothy { | contract TestPropertyValidator { | ||||||
| 
 | 
 | ||||||
|     function getBalance ( |     function validateProperty( | ||||||
|         uint256 tid |         address tokenAddress, | ||||||
|  |         uint256 tokenId, | ||||||
|  |         bytes calldata propertyData | ||||||
|     ) |     ) | ||||||
|         external |         external | ||||||
|         view |         view | ||||||
|         returns (uint256 balance); |     { | ||||||
| 
 |         require( | ||||||
|     function _yBalances ( |             propertyData.length > 0, | ||||||
|         uint256 tid |             "TestPropertyValidator::validateProperty/REVERT" | ||||||
|     ) |         ); | ||||||
|         external |     } | ||||||
|         view |  | ||||||
|         returns (uint256 balance); |  | ||||||
| 
 |  | ||||||
|     function getTokenStats ( |  | ||||||
|         uint256 tid |  | ||||||
|     ) |  | ||||||
|         external |  | ||||||
|         view |  | ||||||
|         returns (uint256 softWeight, uint256 hardWeight, uint256 balance, uint256 decimals); |  | ||||||
| } | } | ||||||
| @@ -21,9 +21,9 @@ pragma solidity ^0.6.5; | |||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
| import "../src/transformers/IERC20Transformer.sol"; | import "../src/transformers/IERC20Transformer.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "./tokens/TestMintableERC20Token.sol"; | ||||||
| import "./TestTransformerHost.sol"; | import "./TestTransformerHost.sol"; | ||||||
| import "./TestWeth.sol"; | import "./tokens/TestWeth.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
| contract TestWethTransformerHost is | contract TestWethTransformerHost is | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ pragma solidity ^0.6.5; | |||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
| 
 | 
 | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "../tokens/TestMintableERC20Token.sol"; | ||||||
| 
 | 
 | ||||||
| contract TestCurve { | contract TestCurve { | ||||||
| 
 | 
 | ||||||
| @@ -21,7 +21,7 @@ pragma solidity ^0.6.5; | |||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
| 
 | 
 | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
| import "./TestMintableERC20Token.sol"; | import "../tokens/TestMintableERC20Token.sol"; | ||||||
| 
 | 
 | ||||||
| contract TestMooniswap { | contract TestMooniswap { | ||||||
| 
 | 
 | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| pragma solidity ^0.6; | pragma solidity ^0.6; | ||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
| import "../src/vendor/IUniswapV2Pair.sol"; | import "../../src/vendor/IUniswapV2Pair.sol"; | ||||||
| 
 | 
 | ||||||
| interface IUniswapV2PoolDeployer { | interface IUniswapV2PoolDeployer { | ||||||
|     struct CreationParameters { |     struct CreationParameters { | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| pragma solidity ^0.6; | pragma solidity ^0.6; | ||||||
| pragma experimental ABIEncoderV2; | pragma experimental ABIEncoderV2; | ||||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||||
| import "../src/vendor/IUniswapV3Pool.sol"; | import "../../src/vendor/IUniswapV3Pool.sol"; | ||||||
| 
 | 
 | ||||||
| interface IUniswapV3PoolDeployer { | interface IUniswapV3PoolDeployer { | ||||||
|     struct CreationParameters { |     struct CreationParameters { | ||||||
| @@ -0,0 +1,345 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2019 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IERC1155Receiver { | ||||||
|  |  | ||||||
|  |     /// @notice Handle the receipt of a single ERC1155 token type | ||||||
|  |     /// @dev The smart contract calls this function on the recipient | ||||||
|  |     /// after a `safeTransferFrom`. This function MAY throw to revert and reject the | ||||||
|  |     /// transfer. Return of other than the magic value MUST result in the | ||||||
|  |     ///transaction being reverted | ||||||
|  |     /// Note: the contract address is always the message sender | ||||||
|  |     /// @param operator  The address which called `safeTransferFrom` function | ||||||
|  |     /// @param from      The address which previously owned the token | ||||||
|  |     /// @param id        An array containing the ids of the token being transferred | ||||||
|  |     /// @param value     An array containing the amount of tokens being transferred | ||||||
|  |     /// @param data      Additional data with no specified format | ||||||
|  |     /// @return success  `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` | ||||||
|  |     function onERC1155Received( | ||||||
|  |         address operator, | ||||||
|  |         address from, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 value, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns(bytes4 success); | ||||||
|  |  | ||||||
|  |     /// @notice Handle the receipt of multiple ERC1155 token types | ||||||
|  |     /// @dev The smart contract calls this function on the recipient | ||||||
|  |     /// after a `safeTransferFrom`. This function MAY throw to revert and reject the | ||||||
|  |     /// transfer. Return of other than the magic value MUST result in the | ||||||
|  |     /// transaction being reverted | ||||||
|  |     /// Note: the contract address is always the message sender | ||||||
|  |     /// @param operator  The address which called `safeTransferFrom` function | ||||||
|  |     /// @param from      The address which previously owned the token | ||||||
|  |     /// @param ids       An array containing ids of each token being transferred | ||||||
|  |     /// @param values    An array containing amounts of each token being transferred | ||||||
|  |     /// @param data      Additional data with no specified format | ||||||
|  |     /// @return success  `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` | ||||||
|  |     function onERC1155BatchReceived( | ||||||
|  |         address operator, | ||||||
|  |         address from, | ||||||
|  |         uint256[] calldata ids, | ||||||
|  |         uint256[] calldata values, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns(bytes4 success); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract TestMintableERC1155Token { | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |  | ||||||
|  |     /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, | ||||||
|  |     ///      including zero value transfers as well as minting or burning. | ||||||
|  |     /// Operator will always be msg.sender. | ||||||
|  |     /// Either event from address `0x0` signifies a minting operation. | ||||||
|  |     /// An event to address `0x0` signifies a burning or melting operation. | ||||||
|  |     /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may | ||||||
|  |     /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID. | ||||||
|  |     /// To define a token ID with no initial balance, the contract SHOULD emit the TransferSingle event | ||||||
|  |     /// from `0x0` to `0x0`, with the token creator as `_operator`. | ||||||
|  |     event TransferSingle( | ||||||
|  |         address indexed operator, | ||||||
|  |         address indexed from, | ||||||
|  |         address indexed to, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 value | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, | ||||||
|  |     ///      including zero value transfers as well as minting or burning. | ||||||
|  |     ///Operator will always be msg.sender. | ||||||
|  |     /// Either event from address `0x0` signifies a minting operation. | ||||||
|  |     /// An event to address `0x0` signifies a burning or melting operation. | ||||||
|  |     /// The total value transferred from address 0x0 minus the total value transferred to 0x0 may | ||||||
|  |     /// be used by clients and exchanges to be added to the "circulating supply" for a given token ID. | ||||||
|  |     /// To define multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event | ||||||
|  |     /// from `0x0` to `0x0`, with the token creator as `_operator`. | ||||||
|  |     event TransferBatch( | ||||||
|  |         address indexed operator, | ||||||
|  |         address indexed from, | ||||||
|  |         address indexed to, | ||||||
|  |         uint256[] ids, | ||||||
|  |         uint256[] values | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev MUST emit when an approval is updated. | ||||||
|  |     event ApprovalForAll( | ||||||
|  |         address indexed owner, | ||||||
|  |         address indexed operator, | ||||||
|  |         bool approved | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     // selectors for receiver callbacks | ||||||
|  |     bytes4 constant public ERC1155_RECEIVED       = 0xf23a6e61; | ||||||
|  |     bytes4 constant public ERC1155_BATCH_RECEIVED = 0xbc197c81; | ||||||
|  |  | ||||||
|  |     // id => (owner => balance) | ||||||
|  |     mapping (uint256 => mapping(address => uint256)) internal balances; | ||||||
|  |  | ||||||
|  |     // owner => (operator => approved) | ||||||
|  |     mapping (address => mapping(address => bool)) internal operatorApproval; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     function mint( | ||||||
|  |         address to, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 quantity | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         // Grant the items to the caller | ||||||
|  |         balances[id][to] = quantity.safeAdd(balances[id][to]); | ||||||
|  |  | ||||||
|  |         // Emit the Transfer/Mint event. | ||||||
|  |         // the 0x0 source address implies a mint | ||||||
|  |         // It will also provide the circulating supply info. | ||||||
|  |         emit TransferSingle( | ||||||
|  |             msg.sender, | ||||||
|  |             address(0x0), | ||||||
|  |             to, | ||||||
|  |             id, | ||||||
|  |             quantity | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // if `to` is a contract then trigger its callback | ||||||
|  |         uint256 receiverCodeSize; | ||||||
|  |         assembly { | ||||||
|  |             receiverCodeSize := extcodesize(to) | ||||||
|  |         } | ||||||
|  |         if (receiverCodeSize > 0) { | ||||||
|  |             bytes4 callbackReturnValue = IERC1155Receiver(to).onERC1155Received( | ||||||
|  |                 msg.sender, | ||||||
|  |                 msg.sender, | ||||||
|  |                 id, | ||||||
|  |                 quantity, | ||||||
|  |                 "" | ||||||
|  |             ); | ||||||
|  |             require( | ||||||
|  |                 callbackReturnValue == ERC1155_RECEIVED, | ||||||
|  |                 "BAD_RECEIVER_RETURN_VALUE" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Transfers value amount of an _id from the _from address to the _to address specified. | ||||||
|  |     /// @dev MUST emit TransferSingle event on success. | ||||||
|  |     /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll). | ||||||
|  |     /// MUST throw if `_to` is the zero address. | ||||||
|  |     /// MUST throw if balance of sender for token `_id` is lower than the `_value` sent. | ||||||
|  |     /// MUST throw on any other error. | ||||||
|  |     /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). | ||||||
|  |     /// If so, it MUST call `onERC1155Received` on `_to` and revert if the return value | ||||||
|  |     /// is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`. | ||||||
|  |     /// @param from    Source address | ||||||
|  |     /// @param to      Target address | ||||||
|  |     /// @param id      ID of the token type | ||||||
|  |     /// @param value   Transfer amount | ||||||
|  |     /// @param data    Additional data with no specified format, sent in call to `_to` | ||||||
|  |     function safeTransferFrom( | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256 id, | ||||||
|  |         uint256 value, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         // sanity checks | ||||||
|  |         require( | ||||||
|  |             to != address(0x0), | ||||||
|  |             "CANNOT_TRANSFER_TO_ADDRESS_ZERO" | ||||||
|  |         ); | ||||||
|  |         require( | ||||||
|  |             from == msg.sender || operatorApproval[from][msg.sender] == true, | ||||||
|  |             "INSUFFICIENT_ALLOWANCE" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // perform transfer | ||||||
|  |         balances[id][from] = balances[id][from].safeSub(value); | ||||||
|  |         balances[id][to] = balances[id][to].safeAdd(value); | ||||||
|  |  | ||||||
|  |         emit TransferSingle(msg.sender, from, to, id, value); | ||||||
|  |  | ||||||
|  |         // if `to` is a contract then trigger its callback | ||||||
|  |         uint256 receiverCodeSize; | ||||||
|  |         assembly { | ||||||
|  |             receiverCodeSize := extcodesize(to) | ||||||
|  |         } | ||||||
|  |         if (receiverCodeSize > 0) { | ||||||
|  |             bytes4 callbackReturnValue = IERC1155Receiver(to).onERC1155Received( | ||||||
|  |                 msg.sender, | ||||||
|  |                 from, | ||||||
|  |                 id, | ||||||
|  |                 value, | ||||||
|  |                 data | ||||||
|  |             ); | ||||||
|  |             require( | ||||||
|  |                 callbackReturnValue == ERC1155_RECEIVED, | ||||||
|  |                 "BAD_RECEIVER_RETURN_VALUE" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Send multiple types of Tokens from a 3rd party in one transfer (with safety call). | ||||||
|  |     /// @dev MUST emit TransferBatch event on success. | ||||||
|  |     /// Caller must be approved to manage the _from account's tokens (see isApprovedForAll). | ||||||
|  |     /// MUST throw if `_to` is the zero address. | ||||||
|  |     /// MUST throw if length of `_ids` is not the same as length of `_values`. | ||||||
|  |     ///  MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_values` sent. | ||||||
|  |     /// MUST throw on any other error. | ||||||
|  |     /// When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). | ||||||
|  |     /// If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return value | ||||||
|  |     /// is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`. | ||||||
|  |     /// @param from    Source addresses | ||||||
|  |     /// @param to      Target addresses | ||||||
|  |     /// @param ids     IDs of each token type | ||||||
|  |     /// @param values  Transfer amounts per token type | ||||||
|  |     /// @param data    Additional data with no specified format, sent in call to `_to` | ||||||
|  |     function safeBatchTransferFrom( | ||||||
|  |         address from, | ||||||
|  |         address to, | ||||||
|  |         uint256[] calldata ids, | ||||||
|  |         uint256[] calldata values, | ||||||
|  |         bytes calldata data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         // sanity checks | ||||||
|  |         require( | ||||||
|  |             to != address(0x0), | ||||||
|  |             "CANNOT_TRANSFER_TO_ADDRESS_ZERO" | ||||||
|  |         ); | ||||||
|  |         require( | ||||||
|  |             ids.length == values.length, | ||||||
|  |             "TOKEN_AND_VALUES_LENGTH_MISMATCH" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // Only supporting a global operator approval allows us to do | ||||||
|  |         // only 1 check and not to touch storage to handle allowances. | ||||||
|  |         require( | ||||||
|  |             from == msg.sender || operatorApproval[from][msg.sender] == true, | ||||||
|  |             "INSUFFICIENT_ALLOWANCE" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // perform transfers | ||||||
|  |         for (uint256 i = 0; i < ids.length; ++i) { | ||||||
|  |             // Cache value to local variable to reduce read costs. | ||||||
|  |             uint256 id = ids[i]; | ||||||
|  |             uint256 value = values[i]; | ||||||
|  |  | ||||||
|  |             balances[id][from] = balances[id][from].safeSub(value); | ||||||
|  |             balances[id][to] = balances[id][to].safeAdd(value); | ||||||
|  |         } | ||||||
|  |         emit TransferBatch(msg.sender, from, to, ids, values); | ||||||
|  |  | ||||||
|  |         // if `to` is a contract then trigger its callback | ||||||
|  |         uint256 receiverCodeSize; | ||||||
|  |         assembly { | ||||||
|  |             receiverCodeSize := extcodesize(to) | ||||||
|  |         } | ||||||
|  |         if (receiverCodeSize > 0) { | ||||||
|  |             bytes4 callbackReturnValue = IERC1155Receiver(to).onERC1155BatchReceived( | ||||||
|  |                 msg.sender, | ||||||
|  |                 from, | ||||||
|  |                 ids, | ||||||
|  |                 values, | ||||||
|  |                 data | ||||||
|  |             ); | ||||||
|  |             require( | ||||||
|  |                 callbackReturnValue == ERC1155_BATCH_RECEIVED, | ||||||
|  |                 "BAD_RECEIVER_RETURN_VALUE" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. | ||||||
|  |     /// @dev MUST emit the ApprovalForAll event on success. | ||||||
|  |     /// @param operator  Address to add to the set of authorized operators | ||||||
|  |     /// @param approved  True if the operator is approved, false to revoke approval | ||||||
|  |     function setApprovalForAll(address operator, bool approved) external { | ||||||
|  |         operatorApproval[msg.sender][operator] = approved; | ||||||
|  |         emit ApprovalForAll(msg.sender, operator, approved); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Queries the approval status of an operator for a given owner. | ||||||
|  |     /// @param owner        The owner of the Tokens | ||||||
|  |     /// @param operator     Address of authorized operator | ||||||
|  |     /// @return isApproved  True if the operator is approved, false if not | ||||||
|  |     function isApprovedForAll(address owner, address operator) external view returns (bool isApproved) { | ||||||
|  |         return operatorApproval[owner][operator]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Get the balance of an account's Tokens. | ||||||
|  |     /// @param owner     The address of the token holder | ||||||
|  |     /// @param id        ID of the Token | ||||||
|  |     /// @return balance  The _owner's balance of the Token type requested | ||||||
|  |     function balanceOf(address owner, uint256 id) external view returns (uint256 balance) { | ||||||
|  |         return balances[id][owner]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Get the balance of multiple account/token pairs | ||||||
|  |     /// @param owners      The addresses of the token holders | ||||||
|  |     /// @param ids         ID of the Tokens | ||||||
|  |     /// @return balances_  The _owner's balance of the Token types requested | ||||||
|  |     function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) external view returns (uint256[] memory balances_) { | ||||||
|  |         // sanity check | ||||||
|  |         require( | ||||||
|  |             owners.length == ids.length, | ||||||
|  |             "OWNERS_AND_IDS_MUST_HAVE_SAME_LENGTH" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         // get balances | ||||||
|  |         balances_ = new uint256[](owners.length); | ||||||
|  |         for (uint256 i = 0; i < owners.length; ++i) { | ||||||
|  |             uint256 id = ids[i]; | ||||||
|  |             balances_[i] = balances[id][owners[i]]; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return balances_; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,385 @@ | |||||||
|  | // SPDX-License-Identifier: Apache-2.0 | ||||||
|  | /* | ||||||
|  |  | ||||||
|  |   Copyright 2020 ZeroEx Intl. | ||||||
|  |  | ||||||
|  |   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |   you may not use this file except in compliance with the License. | ||||||
|  |   You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |   Unless required by applicable law or agreed to in writing, software | ||||||
|  |   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |   See the License for the specific language governing permissions and | ||||||
|  |   limitations under the License. | ||||||
|  |  | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | pragma solidity ^0.6.5; | ||||||
|  | pragma experimental ABIEncoderV2; | ||||||
|  |  | ||||||
|  | import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | interface IERC721Receiver { | ||||||
|  |  | ||||||
|  |     /// @notice Handle the receipt of an NFT | ||||||
|  |     /// @dev The ERC721 smart contract calls this function on the recipient | ||||||
|  |     ///  after a `transfer`. This function MAY throw to revert and reject the | ||||||
|  |     ///  transfer. Return of other than the magic value MUST result in the | ||||||
|  |     ///  transaction being reverted. | ||||||
|  |     ///  Note: the contract address is always the message sender. | ||||||
|  |     /// @param _operator The address which called `safeTransferFrom` function | ||||||
|  |     /// @param _from The address which previously owned the token | ||||||
|  |     /// @param _tokenId The NFT identifier which is being transferred | ||||||
|  |     /// @param _data Additional data with no specified format | ||||||
|  |     /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` | ||||||
|  |     ///  unless throwing | ||||||
|  |     function onERC721Received( | ||||||
|  |         address _operator, | ||||||
|  |         address _from, | ||||||
|  |         uint256 _tokenId, | ||||||
|  |         bytes calldata _data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |         returns (bytes4); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | contract TestMintableERC721Token { | ||||||
|  |     using LibSafeMathV06 for uint256; | ||||||
|  |  | ||||||
|  |     /// @dev This emits when ownership of any NFT changes by any mechanism. | ||||||
|  |     ///      This event emits when NFTs are created (`from` == 0) and destroyed | ||||||
|  |     ///      (`to` == 0). Exception: during contract creation, any number of NFTs | ||||||
|  |     ///      may be created and assigned without emitting Transfer. At the time of | ||||||
|  |     ///      any transfer, the approved address for that NFT (if any) is reset to none. | ||||||
|  |     event Transfer( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev This emits when the approved address for an NFT is changed or | ||||||
|  |     ///      reaffirmed. The zero address indicates there is no approved address. | ||||||
|  |     ///      When a Transfer event emits, this also indicates that the approved | ||||||
|  |     ///      address for that NFT (if any) is reset to none. | ||||||
|  |     event Approval( | ||||||
|  |         address indexed _owner, | ||||||
|  |         address indexed _approved, | ||||||
|  |         uint256 indexed _tokenId | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     /// @dev This emits when an operator is enabled or disabled for an owner. | ||||||
|  |     ///      The operator can manage all NFTs of the owner. | ||||||
|  |     event ApprovalForAll( | ||||||
|  |         address indexed _owner, | ||||||
|  |         address indexed _operator, | ||||||
|  |         bool _approved | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     // Function selector for ERC721Receiver.onERC721Received | ||||||
|  |     // 0x150b7a02 | ||||||
|  |     bytes4 constant private ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); | ||||||
|  |  | ||||||
|  |     // Mapping of tokenId => owner | ||||||
|  |     mapping (uint256 => address) private owners; | ||||||
|  |  | ||||||
|  |     // Mapping of tokenId => approved address | ||||||
|  |     mapping (uint256 => address) private approvals; | ||||||
|  |  | ||||||
|  |     // Mapping of owner => number of tokens owned | ||||||
|  |     mapping (address => uint256) private balances; | ||||||
|  |  | ||||||
|  |     // Mapping of owner => operator => approved | ||||||
|  |     mapping (address => mapping (address => bool)) private operatorApprovals; | ||||||
|  |  | ||||||
|  |     /// @dev Function to mint a new token | ||||||
|  |     ///      Reverts if the given token ID already exists | ||||||
|  |     /// @param _to Address of the beneficiary that will own the minted token | ||||||
|  |     /// @param _tokenId ID of the token to be minted by the msg.sender     | ||||||
|  |     function mint(address _to, uint256 _tokenId) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             _to != address(0), | ||||||
|  |             "ERC721_ZERO_TO_ADDRESS" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         address owner = owners[_tokenId]; | ||||||
|  |         require( | ||||||
|  |             owner == address(0), | ||||||
|  |             "ERC721_OWNER_ALREADY_EXISTS" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         owners[_tokenId] = _to; | ||||||
|  |         balances[_to] = balances[_to].safeAdd(1); | ||||||
|  |  | ||||||
|  |         emit Transfer( | ||||||
|  |             address(0), | ||||||
|  |             _to, | ||||||
|  |             _tokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @dev Function to burn a token | ||||||
|  |     ///      Reverts if the given token ID doesn't exist | ||||||
|  |     /// @param _owner Owner of token with given token ID | ||||||
|  |     /// @param _tokenId ID of the token to be burned by the msg.sender | ||||||
|  |     function burn(address _owner, uint256 _tokenId) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             _owner != address(0), | ||||||
|  |             "ERC721_ZERO_OWNER_ADDRESS" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         address owner = owners[_tokenId]; | ||||||
|  |         require( | ||||||
|  |             owner == _owner, | ||||||
|  |             "ERC721_OWNER_MISMATCH" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         owners[_tokenId] = address(0); | ||||||
|  |         balances[_owner] = balances[_owner].safeSub(1); | ||||||
|  |  | ||||||
|  |         emit Transfer( | ||||||
|  |             _owner, | ||||||
|  |             address(0), | ||||||
|  |             _tokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Transfers the ownership of an NFT from one address to another address | ||||||
|  |     /// @dev Throws unless `msg.sender` is the current owner, an authorized | ||||||
|  |     ///      operator, or the approved address for this NFT. Throws if `_from` is | ||||||
|  |     ///      not the current owner. Throws if `_to` is the zero address. Throws if | ||||||
|  |     ///      `_tokenId` is not a valid NFT. When transfer is complete, this function | ||||||
|  |     ///      checks if `_to` is a smart contract (code size > 0). If so, it calls | ||||||
|  |     ///      `onERC721Received` on `_to` and throws if the return value is not | ||||||
|  |     ///      `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. | ||||||
|  |     /// @param _from The current owner of the NFT | ||||||
|  |     /// @param _to The new owner | ||||||
|  |     /// @param _tokenId The NFT to transfer | ||||||
|  |     /// @param _data Additional data with no specified format, sent in call to `_to` | ||||||
|  |     function safeTransferFrom( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId, | ||||||
|  |         bytes calldata _data | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         transferFrom( | ||||||
|  |             _from, | ||||||
|  |             _to, | ||||||
|  |             _tokenId | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         uint256 receiverCodeSize; | ||||||
|  |         assembly { | ||||||
|  |             receiverCodeSize := extcodesize(_to) | ||||||
|  |         } | ||||||
|  |         if (receiverCodeSize > 0) { | ||||||
|  |             bytes4 selector = IERC721Receiver(_to).onERC721Received( | ||||||
|  |                 msg.sender, | ||||||
|  |                 _from, | ||||||
|  |                 _tokenId, | ||||||
|  |                 _data | ||||||
|  |             ); | ||||||
|  |             require( | ||||||
|  |                 selector == ERC721_RECEIVED, | ||||||
|  |                 "ERC721_INVALID_SELECTOR" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Transfers the ownership of an NFT from one address to another address | ||||||
|  |     /// @dev This works identically to the other function with an extra data parameter, | ||||||
|  |     ///      except this function just sets data to "". | ||||||
|  |     /// @param _from The current owner of the NFT | ||||||
|  |     /// @param _to The new owner | ||||||
|  |     /// @param _tokenId The NFT to transfer | ||||||
|  |     function safeTransferFrom( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId | ||||||
|  |     ) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         transferFrom( | ||||||
|  |             _from, | ||||||
|  |             _to, | ||||||
|  |             _tokenId | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         uint256 receiverCodeSize; | ||||||
|  |         assembly { | ||||||
|  |             receiverCodeSize := extcodesize(_to) | ||||||
|  |         } | ||||||
|  |         if (receiverCodeSize > 0) { | ||||||
|  |             bytes4 selector = IERC721Receiver(_to).onERC721Received( | ||||||
|  |                 msg.sender, | ||||||
|  |                 _from, | ||||||
|  |                 _tokenId, | ||||||
|  |                 "" | ||||||
|  |             ); | ||||||
|  |             require( | ||||||
|  |                 selector == ERC721_RECEIVED, | ||||||
|  |                 "ERC721_INVALID_SELECTOR" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Change or reaffirm the approved address for an NFT | ||||||
|  |     /// @dev The zero address indicates there is no approved address. | ||||||
|  |     ///      Throws unless `msg.sender` is the current NFT owner, or an authorized | ||||||
|  |     ///      operator of the current owner. | ||||||
|  |     /// @param _approved The new approved NFT controller | ||||||
|  |     /// @param _tokenId The NFT to approve | ||||||
|  |     function approve(address _approved, uint256 _tokenId) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         address owner = ownerOf(_tokenId); | ||||||
|  |         require( | ||||||
|  |             msg.sender == owner || isApprovedForAll(owner, msg.sender), | ||||||
|  |             "ERC721_INVALID_SENDER" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         approvals[_tokenId] = _approved; | ||||||
|  |         emit Approval( | ||||||
|  |             owner, | ||||||
|  |             _approved, | ||||||
|  |             _tokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Enable or disable approval for a third party ("operator") to manage | ||||||
|  |     ///         all of `msg.sender`'s assets | ||||||
|  |     /// @dev Emits the ApprovalForAll event. The contract MUST allow | ||||||
|  |     ///      multiple operators per owner. | ||||||
|  |     /// @param _operator Address to add to the set of authorized operators | ||||||
|  |     /// @param _approved True if the operator is approved, false to revoke approval | ||||||
|  |     function setApprovalForAll(address _operator, bool _approved) | ||||||
|  |         external | ||||||
|  |     { | ||||||
|  |         operatorApprovals[msg.sender][_operator] = _approved; | ||||||
|  |         emit ApprovalForAll( | ||||||
|  |             msg.sender, | ||||||
|  |             _operator, | ||||||
|  |             _approved | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Count all NFTs assigned to an owner | ||||||
|  |     /// @dev NFTs assigned to the zero address are considered invalid, and this | ||||||
|  |     ///      function throws for queries about the zero address. | ||||||
|  |     /// @param _owner An address for whom to query the balance | ||||||
|  |     /// @return The number of NFTs owned by `_owner`, possibly zero | ||||||
|  |     function balanceOf(address _owner) | ||||||
|  |         external | ||||||
|  |         view | ||||||
|  |         returns (uint256) | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             _owner != address(0), | ||||||
|  |             "ERC721_ZERO_OWNER" | ||||||
|  |         ); | ||||||
|  |         return balances[_owner]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE | ||||||
|  |     ///         TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE | ||||||
|  |     ///         THEY MAY BE PERMANENTLY LOST | ||||||
|  |     /// @dev Throws unless `msg.sender` is the current owner, an authorized | ||||||
|  |     ///      operator, or the approved address for this NFT. Throws if `_from` is | ||||||
|  |     ///      not the current owner. Throws if `_to` is the zero address. Throws if | ||||||
|  |     ///      `_tokenId` is not a valid NFT. | ||||||
|  |     /// @param _from The current owner of the NFT | ||||||
|  |     /// @param _to The new owner | ||||||
|  |     /// @param _tokenId The NFT to transfer | ||||||
|  |     function transferFrom( | ||||||
|  |         address _from, | ||||||
|  |         address _to, | ||||||
|  |         uint256 _tokenId | ||||||
|  |     ) | ||||||
|  |         public | ||||||
|  |     { | ||||||
|  |         require( | ||||||
|  |             _to != address(0), | ||||||
|  |             "ERC721_ZERO_TO_ADDRESS" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         address owner = ownerOf(_tokenId); | ||||||
|  |         require( | ||||||
|  |             _from == owner, | ||||||
|  |             "ERC721_OWNER_MISMATCH" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         address spender = msg.sender; | ||||||
|  |         address approvedAddress = getApproved(_tokenId); | ||||||
|  |         require( | ||||||
|  |             spender == owner || | ||||||
|  |             isApprovedForAll(owner, spender) || | ||||||
|  |             approvedAddress == spender, | ||||||
|  |             "ERC721_INVALID_SPENDER" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         if (approvedAddress != address(0)) { | ||||||
|  |             approvals[_tokenId] = address(0); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         owners[_tokenId] = _to; | ||||||
|  |         balances[_from] = balances[_from].safeSub(1); | ||||||
|  |         balances[_to] = balances[_to].safeAdd(1); | ||||||
|  |  | ||||||
|  |         emit Transfer( | ||||||
|  |             _from, | ||||||
|  |             _to, | ||||||
|  |             _tokenId | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Find the owner of an NFT | ||||||
|  |     /// @dev NFTs assigned to zero address are considered invalid, and queries | ||||||
|  |     ///      about them do throw. | ||||||
|  |     /// @param _tokenId The identifier for an NFT | ||||||
|  |     /// @return The address of the owner of the NFT | ||||||
|  |     function ownerOf(uint256 _tokenId) | ||||||
|  |         public | ||||||
|  |         view | ||||||
|  |         returns (address) | ||||||
|  |     { | ||||||
|  |         address owner = owners[_tokenId]; | ||||||
|  |         require( | ||||||
|  |             owner != address(0), | ||||||
|  |             "ERC721_ZERO_OWNER" | ||||||
|  |         ); | ||||||
|  |         return owner; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Get the approved address for a single NFT | ||||||
|  |     /// @dev Throws if `_tokenId` is not a valid NFT. | ||||||
|  |     /// @param _tokenId The NFT to find the approved address for | ||||||
|  |     /// @return The approved address for this NFT, or the zero address if there is none | ||||||
|  |     function getApproved(uint256 _tokenId) | ||||||
|  |         public | ||||||
|  |         view | ||||||
|  |         returns (address) | ||||||
|  |     { | ||||||
|  |         return approvals[_tokenId]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// @notice Query if an address is an authorized operator for another address | ||||||
|  |     /// @param _owner The address that owns the NFTs | ||||||
|  |     /// @param _operator The address that acts on behalf of the owner | ||||||
|  |     /// @return True if `_operator` is an approved operator for `_owner`, false otherwise | ||||||
|  |     function isApprovedForAll(address _owner, address _operator) | ||||||
|  |         public | ||||||
|  |         view | ||||||
|  |         returns (bool) | ||||||
|  |     { | ||||||
|  |         return operatorApprovals[_owner][_operator]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|     "name": "@0x/contracts-zero-ex", |     "name": "@0x/contracts-zero-ex", | ||||||
|     "version": "0.30.1", |     "version": "0.36.1", | ||||||
|     "engines": { |     "engines": { | ||||||
|         "node": ">=6.12" |         "node": ">=6.12" | ||||||
|     }, |     }, | ||||||
| @@ -41,9 +41,9 @@ | |||||||
|         "rollback": "node ./lib/scripts/rollback.js" |         "rollback": "node ./lib/scripts/rollback.js" | ||||||
|     }, |     }, | ||||||
|     "config": { |     "config": { | ||||||
|         "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature", |         "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature,AvalancheBridgeAdapter,BSCBridgeAdapter,CeloBridgeAdapter,EthereumBridgeAdapter,FantomBridgeAdapter,OptimismBridgeAdapter,PolygonBridgeAdapter", | ||||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", |         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", | ||||||
|         "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" |         "abis": "./test/generated-artifacts/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinSynthetix|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinVelodrome|MixinWOOFi|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OptimismBridgeAdapter|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PolygonBridgeAdapter|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" | ||||||
|     }, |     }, | ||||||
|     "repository": { |     "repository": { | ||||||
|         "type": "git", |         "type": "git", | ||||||
| @@ -55,14 +55,14 @@ | |||||||
|     }, |     }, | ||||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex", |     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex", | ||||||
|     "devDependencies": { |     "devDependencies": { | ||||||
|         "@0x/abi-gen": "^5.6.2", |         "@0x/abi-gen": "^5.8.0", | ||||||
|         "@0x/contract-addresses": "^6.11.0", |         "@0x/contract-addresses": "^6.19.0", | ||||||
|         "@0x/contracts-erc20": "^3.3.25", |         "@0x/contracts-erc20": "^3.3.34", | ||||||
|         "@0x/contracts-gen": "^2.0.40", |         "@0x/contracts-gen": "^2.0.46", | ||||||
|         "@0x/contracts-test-utils": "^5.4.16", |         "@0x/contracts-test-utils": "^5.4.25", | ||||||
|         "@0x/dev-utils": "^4.2.9", |         "@0x/dev-utils": "^4.2.14", | ||||||
|         "@0x/order-utils": "^10.4.28", |         "@0x/order-utils": "^10.4.28", | ||||||
|         "@0x/sol-compiler": "^4.7.5", |         "@0x/sol-compiler": "^4.8.1", | ||||||
|         "@0x/ts-doc-gen": "^0.0.28", |         "@0x/ts-doc-gen": "^0.0.28", | ||||||
|         "@0x/tslint-config": "^4.1.4", |         "@0x/tslint-config": "^4.1.4", | ||||||
|         "@types/isomorphic-fetch": "^0.0.35", |         "@types/isomorphic-fetch": "^0.0.35", | ||||||
| @@ -79,17 +79,17 @@ | |||||||
|         "truffle": "^5.0.32", |         "truffle": "^5.0.32", | ||||||
|         "tslint": "5.11.0", |         "tslint": "5.11.0", | ||||||
|         "typedoc": "~0.16.11", |         "typedoc": "~0.16.11", | ||||||
|         "typescript": "4.2.2" |         "typescript": "4.6.3" | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|         "@0x/base-contract": "^6.4.2", |         "@0x/base-contract": "^6.5.0", | ||||||
|         "@0x/protocol-utils": "^1.10.1", |         "@0x/protocol-utils": "^11.16.1", | ||||||
|         "@0x/subproviders": "^6.6.0", |         "@0x/subproviders": "^6.6.5", | ||||||
|         "@0x/types": "^3.3.4", |         "@0x/types": "^3.3.6", | ||||||
|         "@0x/typescript-typings": "^5.2.1", |         "@0x/typescript-typings": "^5.3.1", | ||||||
|         "@0x/utils": "^6.4.4", |         "@0x/utils": "^6.5.3", | ||||||
|         "@0x/web3-wrapper": "^7.6.0", |         "@0x/web3-wrapper": "^7.6.5", | ||||||
|         "ethereum-types": "^3.6.0", |         "ethereum-types": "^3.7.0", | ||||||
|         "ethereumjs-util": "^7.0.10", |         "ethereumjs-util": "^7.0.10", | ||||||
|         "ethers": "~4.0.4" |         "ethers": "~4.0.4" | ||||||
|     }, |     }, | ||||||
|   | |||||||
| @@ -6,9 +6,13 @@ | |||||||
| import { ContractArtifact } from 'ethereum-types'; | import { ContractArtifact } from 'ethereum-types'; | ||||||
|  |  | ||||||
| import * as AffiliateFeeTransformer from '../generated-artifacts/AffiliateFeeTransformer.json'; | import * as AffiliateFeeTransformer from '../generated-artifacts/AffiliateFeeTransformer.json'; | ||||||
|  | import * as AvalancheBridgeAdapter from '../generated-artifacts/AvalancheBridgeAdapter.json'; | ||||||
| import * as BatchFillNativeOrdersFeature from '../generated-artifacts/BatchFillNativeOrdersFeature.json'; | import * as BatchFillNativeOrdersFeature from '../generated-artifacts/BatchFillNativeOrdersFeature.json'; | ||||||
| import * as BridgeAdapter from '../generated-artifacts/BridgeAdapter.json'; | import * as BSCBridgeAdapter from '../generated-artifacts/BSCBridgeAdapter.json'; | ||||||
|  | import * as CeloBridgeAdapter from '../generated-artifacts/CeloBridgeAdapter.json'; | ||||||
| import * as CurveLiquidityProvider from '../generated-artifacts/CurveLiquidityProvider.json'; | import * as CurveLiquidityProvider from '../generated-artifacts/CurveLiquidityProvider.json'; | ||||||
|  | import * as EthereumBridgeAdapter from '../generated-artifacts/EthereumBridgeAdapter.json'; | ||||||
|  | import * as FantomBridgeAdapter from '../generated-artifacts/FantomBridgeAdapter.json'; | ||||||
| import * as FeeCollector from '../generated-artifacts/FeeCollector.json'; | import * as FeeCollector from '../generated-artifacts/FeeCollector.json'; | ||||||
| import * as FeeCollectorController from '../generated-artifacts/FeeCollectorController.json'; | import * as FeeCollectorController from '../generated-artifacts/FeeCollectorController.json'; | ||||||
| import * as FillQuoteTransformer from '../generated-artifacts/FillQuoteTransformer.json'; | import * as FillQuoteTransformer from '../generated-artifacts/FillQuoteTransformer.json'; | ||||||
| @@ -30,9 +34,11 @@ import * as LogMetadataTransformer from '../generated-artifacts/LogMetadataTrans | |||||||
| import * as MetaTransactionsFeature from '../generated-artifacts/MetaTransactionsFeature.json'; | import * as MetaTransactionsFeature from '../generated-artifacts/MetaTransactionsFeature.json'; | ||||||
| import * as MultiplexFeature from '../generated-artifacts/MultiplexFeature.json'; | import * as MultiplexFeature from '../generated-artifacts/MultiplexFeature.json'; | ||||||
| import * as NativeOrdersFeature from '../generated-artifacts/NativeOrdersFeature.json'; | import * as NativeOrdersFeature from '../generated-artifacts/NativeOrdersFeature.json'; | ||||||
|  | import * as OptimismBridgeAdapter from '../generated-artifacts/OptimismBridgeAdapter.json'; | ||||||
| import * as OtcOrdersFeature from '../generated-artifacts/OtcOrdersFeature.json'; | import * as OtcOrdersFeature from '../generated-artifacts/OtcOrdersFeature.json'; | ||||||
| import * as OwnableFeature from '../generated-artifacts/OwnableFeature.json'; | import * as OwnableFeature from '../generated-artifacts/OwnableFeature.json'; | ||||||
| import * as PayTakerTransformer from '../generated-artifacts/PayTakerTransformer.json'; | import * as PayTakerTransformer from '../generated-artifacts/PayTakerTransformer.json'; | ||||||
|  | import * as PolygonBridgeAdapter from '../generated-artifacts/PolygonBridgeAdapter.json'; | ||||||
| import * as PositiveSlippageFeeTransformer from '../generated-artifacts/PositiveSlippageFeeTransformer.json'; | import * as PositiveSlippageFeeTransformer from '../generated-artifacts/PositiveSlippageFeeTransformer.json'; | ||||||
| import * as SimpleFunctionRegistryFeature from '../generated-artifacts/SimpleFunctionRegistryFeature.json'; | import * as SimpleFunctionRegistryFeature from '../generated-artifacts/SimpleFunctionRegistryFeature.json'; | ||||||
| import * as TransformERC20Feature from '../generated-artifacts/TransformERC20Feature.json'; | import * as TransformERC20Feature from '../generated-artifacts/TransformERC20Feature.json'; | ||||||
| @@ -58,7 +64,6 @@ export const artifacts = { | |||||||
|     AffiliateFeeTransformer: AffiliateFeeTransformer as ContractArtifact, |     AffiliateFeeTransformer: AffiliateFeeTransformer as ContractArtifact, | ||||||
|     MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact, |     MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact, | ||||||
|     LogMetadataTransformer: LogMetadataTransformer as ContractArtifact, |     LogMetadataTransformer: LogMetadataTransformer as ContractArtifact, | ||||||
|     BridgeAdapter: BridgeAdapter as ContractArtifact, |  | ||||||
|     LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact, |     LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact, | ||||||
|     ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact, |     ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact, | ||||||
|     NativeOrdersFeature: NativeOrdersFeature as ContractArtifact, |     NativeOrdersFeature: NativeOrdersFeature as ContractArtifact, | ||||||
| @@ -72,4 +77,11 @@ export const artifacts = { | |||||||
|     IMultiplexFeature: IMultiplexFeature as ContractArtifact, |     IMultiplexFeature: IMultiplexFeature as ContractArtifact, | ||||||
|     OtcOrdersFeature: OtcOrdersFeature as ContractArtifact, |     OtcOrdersFeature: OtcOrdersFeature as ContractArtifact, | ||||||
|     IOtcOrdersFeature: IOtcOrdersFeature as ContractArtifact, |     IOtcOrdersFeature: IOtcOrdersFeature as ContractArtifact, | ||||||
|  |     AvalancheBridgeAdapter: AvalancheBridgeAdapter as ContractArtifact, | ||||||
|  |     BSCBridgeAdapter: BSCBridgeAdapter as ContractArtifact, | ||||||
|  |     CeloBridgeAdapter: CeloBridgeAdapter as ContractArtifact, | ||||||
|  |     EthereumBridgeAdapter: EthereumBridgeAdapter as ContractArtifact, | ||||||
|  |     FantomBridgeAdapter: FantomBridgeAdapter as ContractArtifact, | ||||||
|  |     OptimismBridgeAdapter: OptimismBridgeAdapter as ContractArtifact, | ||||||
|  |     PolygonBridgeAdapter: PolygonBridgeAdapter as ContractArtifact, | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -35,7 +35,11 @@ export * from './bloom_filter_utils'; | |||||||
| export { GREEDY_TOKENS } from './constants'; | export { GREEDY_TOKENS } from './constants'; | ||||||
| export { | export { | ||||||
|     AffiliateFeeTransformerContract, |     AffiliateFeeTransformerContract, | ||||||
|     BridgeAdapterContract, |     AvalancheBridgeAdapterContract, | ||||||
|  |     BSCBridgeAdapterContract, | ||||||
|  |     CeloBridgeAdapterContract, | ||||||
|  |     EthereumBridgeAdapterContract, | ||||||
|  |     FantomBridgeAdapterContract, | ||||||
|     FillQuoteTransformerContract, |     FillQuoteTransformerContract, | ||||||
|     IOwnableFeatureContract, |     IOwnableFeatureContract, | ||||||
|     IOwnableFeatureEvents, |     IOwnableFeatureEvents, | ||||||
| @@ -45,7 +49,9 @@ export { | |||||||
|     IZeroExContract, |     IZeroExContract, | ||||||
|     LogMetadataTransformerContract, |     LogMetadataTransformerContract, | ||||||
|     MultiplexFeatureContract, |     MultiplexFeatureContract, | ||||||
|  |     OptimismBridgeAdapterContract, | ||||||
|     PayTakerTransformerContract, |     PayTakerTransformerContract, | ||||||
|  |     PolygonBridgeAdapterContract, | ||||||
|     PositiveSlippageFeeTransformerContract, |     PositiveSlippageFeeTransformerContract, | ||||||
|     TransformERC20FeatureContract, |     TransformERC20FeatureContract, | ||||||
|     WethTransformerContract, |     WethTransformerContract, | ||||||
|   | |||||||
| @@ -4,9 +4,13 @@ | |||||||
|  * ----------------------------------------------------------------------------- |  * ----------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| export * from '../generated-wrappers/affiliate_fee_transformer'; | export * from '../generated-wrappers/affiliate_fee_transformer'; | ||||||
|  | export * from '../generated-wrappers/avalanche_bridge_adapter'; | ||||||
|  | export * from '../generated-wrappers/b_s_c_bridge_adapter'; | ||||||
| export * from '../generated-wrappers/batch_fill_native_orders_feature'; | export * from '../generated-wrappers/batch_fill_native_orders_feature'; | ||||||
| export * from '../generated-wrappers/bridge_adapter'; | export * from '../generated-wrappers/celo_bridge_adapter'; | ||||||
| export * from '../generated-wrappers/curve_liquidity_provider'; | export * from '../generated-wrappers/curve_liquidity_provider'; | ||||||
|  | export * from '../generated-wrappers/ethereum_bridge_adapter'; | ||||||
|  | export * from '../generated-wrappers/fantom_bridge_adapter'; | ||||||
| export * from '../generated-wrappers/fee_collector'; | export * from '../generated-wrappers/fee_collector'; | ||||||
| export * from '../generated-wrappers/fee_collector_controller'; | export * from '../generated-wrappers/fee_collector_controller'; | ||||||
| export * from '../generated-wrappers/fill_quote_transformer'; | export * from '../generated-wrappers/fill_quote_transformer'; | ||||||
| @@ -28,9 +32,11 @@ export * from '../generated-wrappers/log_metadata_transformer'; | |||||||
| export * from '../generated-wrappers/meta_transactions_feature'; | export * from '../generated-wrappers/meta_transactions_feature'; | ||||||
| export * from '../generated-wrappers/multiplex_feature'; | export * from '../generated-wrappers/multiplex_feature'; | ||||||
| export * from '../generated-wrappers/native_orders_feature'; | export * from '../generated-wrappers/native_orders_feature'; | ||||||
|  | export * from '../generated-wrappers/optimism_bridge_adapter'; | ||||||
| export * from '../generated-wrappers/otc_orders_feature'; | export * from '../generated-wrappers/otc_orders_feature'; | ||||||
| export * from '../generated-wrappers/ownable_feature'; | export * from '../generated-wrappers/ownable_feature'; | ||||||
| export * from '../generated-wrappers/pay_taker_transformer'; | export * from '../generated-wrappers/pay_taker_transformer'; | ||||||
|  | export * from '../generated-wrappers/polygon_bridge_adapter'; | ||||||
| export * from '../generated-wrappers/positive_slippage_fee_transformer'; | export * from '../generated-wrappers/positive_slippage_fee_transformer'; | ||||||
| export * from '../generated-wrappers/simple_function_registry_feature'; | export * from '../generated-wrappers/simple_function_registry_feature'; | ||||||
| export * from '../generated-wrappers/transform_erc20_feature'; | export * from '../generated-wrappers/transform_erc20_feature'; | ||||||
|   | |||||||
| @@ -5,17 +5,27 @@ | |||||||
|  */ |  */ | ||||||
| import { ContractArtifact } from 'ethereum-types'; | import { ContractArtifact } from 'ethereum-types'; | ||||||
|  |  | ||||||
|  | import * as AbstractBridgeAdapter from '../test/generated-artifacts/AbstractBridgeAdapter.json'; | ||||||
| import * as AffiliateFeeTransformer from '../test/generated-artifacts/AffiliateFeeTransformer.json'; | import * as AffiliateFeeTransformer from '../test/generated-artifacts/AffiliateFeeTransformer.json'; | ||||||
|  | import * as AvalancheBridgeAdapter from '../test/generated-artifacts/AvalancheBridgeAdapter.json'; | ||||||
| import * as BatchFillNativeOrdersFeature from '../test/generated-artifacts/BatchFillNativeOrdersFeature.json'; | import * as BatchFillNativeOrdersFeature from '../test/generated-artifacts/BatchFillNativeOrdersFeature.json'; | ||||||
| import * as BootstrapFeature from '../test/generated-artifacts/BootstrapFeature.json'; | import * as BootstrapFeature from '../test/generated-artifacts/BootstrapFeature.json'; | ||||||
| import * as BridgeAdapter from '../test/generated-artifacts/BridgeAdapter.json'; |  | ||||||
| import * as BridgeProtocols from '../test/generated-artifacts/BridgeProtocols.json'; | import * as BridgeProtocols from '../test/generated-artifacts/BridgeProtocols.json'; | ||||||
|  | import * as BSCBridgeAdapter from '../test/generated-artifacts/BSCBridgeAdapter.json'; | ||||||
|  | import * as CeloBridgeAdapter from '../test/generated-artifacts/CeloBridgeAdapter.json'; | ||||||
| import * as CurveLiquidityProvider from '../test/generated-artifacts/CurveLiquidityProvider.json'; | import * as CurveLiquidityProvider from '../test/generated-artifacts/CurveLiquidityProvider.json'; | ||||||
|  | import * as ERC1155OrdersFeature from '../test/generated-artifacts/ERC1155OrdersFeature.json'; | ||||||
|  | import * as ERC165Feature from '../test/generated-artifacts/ERC165Feature.json'; | ||||||
|  | import * as ERC721OrdersFeature from '../test/generated-artifacts/ERC721OrdersFeature.json'; | ||||||
|  | import * as EthereumBridgeAdapter from '../test/generated-artifacts/EthereumBridgeAdapter.json'; | ||||||
|  | import * as FantomBridgeAdapter from '../test/generated-artifacts/FantomBridgeAdapter.json'; | ||||||
| import * as FeeCollector from '../test/generated-artifacts/FeeCollector.json'; | import * as FeeCollector from '../test/generated-artifacts/FeeCollector.json'; | ||||||
| import * as FeeCollectorController from '../test/generated-artifacts/FeeCollectorController.json'; | import * as FeeCollectorController from '../test/generated-artifacts/FeeCollectorController.json'; | ||||||
| import * as FillQuoteTransformer from '../test/generated-artifacts/FillQuoteTransformer.json'; | import * as FillQuoteTransformer from '../test/generated-artifacts/FillQuoteTransformer.json'; | ||||||
| import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json'; | import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json'; | ||||||
| import * as FixinEIP712 from '../test/generated-artifacts/FixinEIP712.json'; | import * as FixinEIP712 from '../test/generated-artifacts/FixinEIP712.json'; | ||||||
|  | import * as FixinERC1155Spender from '../test/generated-artifacts/FixinERC1155Spender.json'; | ||||||
|  | import * as FixinERC721Spender from '../test/generated-artifacts/FixinERC721Spender.json'; | ||||||
| import * as FixinProtocolFees from '../test/generated-artifacts/FixinProtocolFees.json'; | import * as FixinProtocolFees from '../test/generated-artifacts/FixinProtocolFees.json'; | ||||||
| import * as FixinReentrancyGuard from '../test/generated-artifacts/FixinReentrancyGuard.json'; | import * as FixinReentrancyGuard from '../test/generated-artifacts/FixinReentrancyGuard.json'; | ||||||
| import * as FixinTokenSpender from '../test/generated-artifacts/FixinTokenSpender.json'; | import * as FixinTokenSpender from '../test/generated-artifacts/FixinTokenSpender.json'; | ||||||
| @@ -25,9 +35,15 @@ import * as FundRecoveryFeature from '../test/generated-artifacts/FundRecoveryFe | |||||||
| import * as IBatchFillNativeOrdersFeature from '../test/generated-artifacts/IBatchFillNativeOrdersFeature.json'; | import * as IBatchFillNativeOrdersFeature from '../test/generated-artifacts/IBatchFillNativeOrdersFeature.json'; | ||||||
| import * as IBootstrapFeature from '../test/generated-artifacts/IBootstrapFeature.json'; | import * as IBootstrapFeature from '../test/generated-artifacts/IBootstrapFeature.json'; | ||||||
| import * as IBridgeAdapter from '../test/generated-artifacts/IBridgeAdapter.json'; | import * as IBridgeAdapter from '../test/generated-artifacts/IBridgeAdapter.json'; | ||||||
|  | import * as IERC1155OrdersFeature from '../test/generated-artifacts/IERC1155OrdersFeature.json'; | ||||||
|  | import * as IERC1155Token from '../test/generated-artifacts/IERC1155Token.json'; | ||||||
|  | import * as IERC165Feature from '../test/generated-artifacts/IERC165Feature.json'; | ||||||
| import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json'; | import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json'; | ||||||
| import * as IERC20Transformer from '../test/generated-artifacts/IERC20Transformer.json'; | import * as IERC20Transformer from '../test/generated-artifacts/IERC20Transformer.json'; | ||||||
|  | import * as IERC721OrdersFeature from '../test/generated-artifacts/IERC721OrdersFeature.json'; | ||||||
|  | import * as IERC721Token from '../test/generated-artifacts/IERC721Token.json'; | ||||||
| import * as IFeature from '../test/generated-artifacts/IFeature.json'; | import * as IFeature from '../test/generated-artifacts/IFeature.json'; | ||||||
|  | import * as IFeeRecipient from '../test/generated-artifacts/IFeeRecipient.json'; | ||||||
| import * as IFlashWallet from '../test/generated-artifacts/IFlashWallet.json'; | import * as IFlashWallet from '../test/generated-artifacts/IFlashWallet.json'; | ||||||
| import * as IFundRecoveryFeature from '../test/generated-artifacts/IFundRecoveryFeature.json'; | import * as IFundRecoveryFeature from '../test/generated-artifacts/IFundRecoveryFeature.json'; | ||||||
| import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json'; | import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json'; | ||||||
| @@ -42,8 +58,10 @@ import * as InitialMigration from '../test/generated-artifacts/InitialMigration. | |||||||
| import * as IOtcOrdersFeature from '../test/generated-artifacts/IOtcOrdersFeature.json'; | import * as IOtcOrdersFeature from '../test/generated-artifacts/IOtcOrdersFeature.json'; | ||||||
| import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json'; | import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json'; | ||||||
| import * as IPancakeSwapFeature from '../test/generated-artifacts/IPancakeSwapFeature.json'; | import * as IPancakeSwapFeature from '../test/generated-artifacts/IPancakeSwapFeature.json'; | ||||||
|  | import * as IPropertyValidator from '../test/generated-artifacts/IPropertyValidator.json'; | ||||||
| import * as ISimpleFunctionRegistryFeature from '../test/generated-artifacts/ISimpleFunctionRegistryFeature.json'; | import * as ISimpleFunctionRegistryFeature from '../test/generated-artifacts/ISimpleFunctionRegistryFeature.json'; | ||||||
| import * as IStaking from '../test/generated-artifacts/IStaking.json'; | import * as IStaking from '../test/generated-artifacts/IStaking.json'; | ||||||
|  | import * as ITakerCallback from '../test/generated-artifacts/ITakerCallback.json'; | ||||||
| import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json'; | import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json'; | ||||||
| import * as ITokenSpenderFeature from '../test/generated-artifacts/ITokenSpenderFeature.json'; | import * as ITokenSpenderFeature from '../test/generated-artifacts/ITokenSpenderFeature.json'; | ||||||
| import * as ITransformERC20Feature from '../test/generated-artifacts/ITransformERC20Feature.json'; | import * as ITransformERC20Feature from '../test/generated-artifacts/ITransformERC20Feature.json'; | ||||||
| @@ -54,7 +72,9 @@ import * as IUniswapV3Pool from '../test/generated-artifacts/IUniswapV3Pool.json | |||||||
| import * as IZeroEx from '../test/generated-artifacts/IZeroEx.json'; | import * as IZeroEx from '../test/generated-artifacts/IZeroEx.json'; | ||||||
| import * as LibBootstrap from '../test/generated-artifacts/LibBootstrap.json'; | import * as LibBootstrap from '../test/generated-artifacts/LibBootstrap.json'; | ||||||
| import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json'; | import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json'; | ||||||
|  | import * as LibERC1155OrdersStorage from '../test/generated-artifacts/LibERC1155OrdersStorage.json'; | ||||||
| import * as LibERC20Transformer from '../test/generated-artifacts/LibERC20Transformer.json'; | import * as LibERC20Transformer from '../test/generated-artifacts/LibERC20Transformer.json'; | ||||||
|  | import * as LibERC721OrdersStorage from '../test/generated-artifacts/LibERC721OrdersStorage.json'; | ||||||
| import * as LibFeeCollector from '../test/generated-artifacts/LibFeeCollector.json'; | import * as LibFeeCollector from '../test/generated-artifacts/LibFeeCollector.json'; | ||||||
| import * as LibLiquidityProviderRichErrors from '../test/generated-artifacts/LibLiquidityProviderRichErrors.json'; | import * as LibLiquidityProviderRichErrors from '../test/generated-artifacts/LibLiquidityProviderRichErrors.json'; | ||||||
| import * as LibMetaTransactionsRichErrors from '../test/generated-artifacts/LibMetaTransactionsRichErrors.json'; | import * as LibMetaTransactionsRichErrors from '../test/generated-artifacts/LibMetaTransactionsRichErrors.json'; | ||||||
| @@ -63,6 +83,8 @@ import * as LibMigrate from '../test/generated-artifacts/LibMigrate.json'; | |||||||
| import * as LibNativeOrder from '../test/generated-artifacts/LibNativeOrder.json'; | import * as LibNativeOrder from '../test/generated-artifacts/LibNativeOrder.json'; | ||||||
| import * as LibNativeOrdersRichErrors from '../test/generated-artifacts/LibNativeOrdersRichErrors.json'; | import * as LibNativeOrdersRichErrors from '../test/generated-artifacts/LibNativeOrdersRichErrors.json'; | ||||||
| import * as LibNativeOrdersStorage from '../test/generated-artifacts/LibNativeOrdersStorage.json'; | import * as LibNativeOrdersStorage from '../test/generated-artifacts/LibNativeOrdersStorage.json'; | ||||||
|  | import * as LibNFTOrder from '../test/generated-artifacts/LibNFTOrder.json'; | ||||||
|  | import * as LibNFTOrdersRichErrors from '../test/generated-artifacts/LibNFTOrdersRichErrors.json'; | ||||||
| import * as LibOtcOrdersStorage from '../test/generated-artifacts/LibOtcOrdersStorage.json'; | import * as LibOtcOrdersStorage from '../test/generated-artifacts/LibOtcOrdersStorage.json'; | ||||||
| import * as LibOwnableRichErrors from '../test/generated-artifacts/LibOwnableRichErrors.json'; | import * as LibOwnableRichErrors from '../test/generated-artifacts/LibOwnableRichErrors.json'; | ||||||
| import * as LibOwnableStorage from '../test/generated-artifacts/LibOwnableStorage.json'; | import * as LibOwnableStorage from '../test/generated-artifacts/LibOwnableStorage.json'; | ||||||
| @@ -84,26 +106,30 @@ import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransa | |||||||
| import * as MixinAaveV2 from '../test/generated-artifacts/MixinAaveV2.json'; | import * as MixinAaveV2 from '../test/generated-artifacts/MixinAaveV2.json'; | ||||||
| import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json'; | import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json'; | ||||||
| import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json'; | import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json'; | ||||||
|  | import * as MixinBalancerV2Batch from '../test/generated-artifacts/MixinBalancerV2Batch.json'; | ||||||
| import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json'; | import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json'; | ||||||
| import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json'; | import * as MixinBancorV3 from '../test/generated-artifacts/MixinBancorV3.json'; | ||||||
| import * as MixinCompound from '../test/generated-artifacts/MixinCompound.json'; | import * as MixinCompound from '../test/generated-artifacts/MixinCompound.json'; | ||||||
| import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json'; | import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json'; | ||||||
| import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json'; | import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json'; | ||||||
| import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json'; | import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json'; | ||||||
| import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json'; | import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json'; | ||||||
| import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json'; | import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json'; | ||||||
| import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json'; | import * as MixinGMX from '../test/generated-artifacts/MixinGMX.json'; | ||||||
| import * as MixinKyberDmm from '../test/generated-artifacts/MixinKyberDmm.json'; | import * as MixinKyberDmm from '../test/generated-artifacts/MixinKyberDmm.json'; | ||||||
| import * as MixinLido from '../test/generated-artifacts/MixinLido.json'; | import * as MixinLido from '../test/generated-artifacts/MixinLido.json'; | ||||||
| import * as MixinMakerPSM from '../test/generated-artifacts/MixinMakerPSM.json'; | import * as MixinMakerPSM from '../test/generated-artifacts/MixinMakerPSM.json'; | ||||||
| import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json'; | import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json'; | ||||||
| import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json'; | import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json'; | ||||||
| import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json'; | import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json'; | ||||||
| import * as MixinOasis from '../test/generated-artifacts/MixinOasis.json'; | import * as MixinPlatypus from '../test/generated-artifacts/MixinPlatypus.json'; | ||||||
| import * as MixinShell from '../test/generated-artifacts/MixinShell.json'; | import * as MixinShell from '../test/generated-artifacts/MixinShell.json'; | ||||||
|  | import * as MixinSynthetix from '../test/generated-artifacts/MixinSynthetix.json'; | ||||||
| import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json'; | import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json'; | ||||||
| import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json'; | import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json'; | ||||||
| import * as MixinUniswapV3 from '../test/generated-artifacts/MixinUniswapV3.json'; | import * as MixinUniswapV3 from '../test/generated-artifacts/MixinUniswapV3.json'; | ||||||
|  | import * as MixinVelodrome from '../test/generated-artifacts/MixinVelodrome.json'; | ||||||
|  | import * as MixinWOOFi from '../test/generated-artifacts/MixinWOOFi.json'; | ||||||
| import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridge.json'; | import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridge.json'; | ||||||
| import * as MooniswapLiquidityProvider from '../test/generated-artifacts/MooniswapLiquidityProvider.json'; | import * as MooniswapLiquidityProvider from '../test/generated-artifacts/MooniswapLiquidityProvider.json'; | ||||||
| import * as MultiplexFeature from '../test/generated-artifacts/MultiplexFeature.json'; | import * as MultiplexFeature from '../test/generated-artifacts/MultiplexFeature.json'; | ||||||
| @@ -118,11 +144,14 @@ import * as NativeOrdersFeature from '../test/generated-artifacts/NativeOrdersFe | |||||||
| import * as NativeOrdersInfo from '../test/generated-artifacts/NativeOrdersInfo.json'; | import * as NativeOrdersInfo from '../test/generated-artifacts/NativeOrdersInfo.json'; | ||||||
| import * as NativeOrdersProtocolFees from '../test/generated-artifacts/NativeOrdersProtocolFees.json'; | import * as NativeOrdersProtocolFees from '../test/generated-artifacts/NativeOrdersProtocolFees.json'; | ||||||
| import * as NativeOrdersSettlement from '../test/generated-artifacts/NativeOrdersSettlement.json'; | import * as NativeOrdersSettlement from '../test/generated-artifacts/NativeOrdersSettlement.json'; | ||||||
|  | import * as NFTOrders from '../test/generated-artifacts/NFTOrders.json'; | ||||||
|  | import * as OptimismBridgeAdapter from '../test/generated-artifacts/OptimismBridgeAdapter.json'; | ||||||
| import * as OtcOrdersFeature from '../test/generated-artifacts/OtcOrdersFeature.json'; | import * as OtcOrdersFeature from '../test/generated-artifacts/OtcOrdersFeature.json'; | ||||||
| import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json'; | import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json'; | ||||||
| import * as PancakeSwapFeature from '../test/generated-artifacts/PancakeSwapFeature.json'; | import * as PancakeSwapFeature from '../test/generated-artifacts/PancakeSwapFeature.json'; | ||||||
| import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.json'; | import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.json'; | ||||||
| import * as PermissionlessTransformerDeployer from '../test/generated-artifacts/PermissionlessTransformerDeployer.json'; | import * as PermissionlessTransformerDeployer from '../test/generated-artifacts/PermissionlessTransformerDeployer.json'; | ||||||
|  | import * as PolygonBridgeAdapter from '../test/generated-artifacts/PolygonBridgeAdapter.json'; | ||||||
| import * as PositiveSlippageFeeTransformer from '../test/generated-artifacts/PositiveSlippageFeeTransformer.json'; | import * as PositiveSlippageFeeTransformer from '../test/generated-artifacts/PositiveSlippageFeeTransformer.json'; | ||||||
| import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json'; | import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json'; | ||||||
| import * as TestBridge from '../test/generated-artifacts/TestBridge.json'; | import * as TestBridge from '../test/generated-artifacts/TestBridge.json'; | ||||||
| @@ -130,6 +159,7 @@ import * as TestCallTarget from '../test/generated-artifacts/TestCallTarget.json | |||||||
| import * as TestCurve from '../test/generated-artifacts/TestCurve.json'; | import * as TestCurve from '../test/generated-artifacts/TestCurve.json'; | ||||||
| import * as TestDelegateCaller from '../test/generated-artifacts/TestDelegateCaller.json'; | import * as TestDelegateCaller from '../test/generated-artifacts/TestDelegateCaller.json'; | ||||||
| import * as TestFeeCollectorController from '../test/generated-artifacts/TestFeeCollectorController.json'; | import * as TestFeeCollectorController from '../test/generated-artifacts/TestFeeCollectorController.json'; | ||||||
|  | import * as TestFeeRecipient from '../test/generated-artifacts/TestFeeRecipient.json'; | ||||||
| import * as TestFillQuoteTransformerBridge from '../test/generated-artifacts/TestFillQuoteTransformerBridge.json'; | import * as TestFillQuoteTransformerBridge from '../test/generated-artifacts/TestFillQuoteTransformerBridge.json'; | ||||||
| import * as TestFillQuoteTransformerExchange from '../test/generated-artifacts/TestFillQuoteTransformerExchange.json'; | import * as TestFillQuoteTransformerExchange from '../test/generated-artifacts/TestFillQuoteTransformerExchange.json'; | ||||||
| import * as TestFillQuoteTransformerHost from '../test/generated-artifacts/TestFillQuoteTransformerHost.json'; | import * as TestFillQuoteTransformerHost from '../test/generated-artifacts/TestFillQuoteTransformerHost.json'; | ||||||
| @@ -143,14 +173,18 @@ import * as TestLiquidityProvider from '../test/generated-artifacts/TestLiquidit | |||||||
| import * as TestMetaTransactionsNativeOrdersFeature from '../test/generated-artifacts/TestMetaTransactionsNativeOrdersFeature.json'; | import * as TestMetaTransactionsNativeOrdersFeature from '../test/generated-artifacts/TestMetaTransactionsNativeOrdersFeature.json'; | ||||||
| import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json'; | import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json'; | ||||||
| import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json'; | import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json'; | ||||||
|  | import * as TestMintableERC1155Token from '../test/generated-artifacts/TestMintableERC1155Token.json'; | ||||||
| import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json'; | import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json'; | ||||||
|  | import * as TestMintableERC721Token from '../test/generated-artifacts/TestMintableERC721Token.json'; | ||||||
| import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json'; | import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json'; | ||||||
| import * as TestMooniswap from '../test/generated-artifacts/TestMooniswap.json'; | import * as TestMooniswap from '../test/generated-artifacts/TestMooniswap.json'; | ||||||
| import * as TestNativeOrdersFeature from '../test/generated-artifacts/TestNativeOrdersFeature.json'; | import * as TestNativeOrdersFeature from '../test/generated-artifacts/TestNativeOrdersFeature.json'; | ||||||
|  | import * as TestNFTOrderPresigner from '../test/generated-artifacts/TestNFTOrderPresigner.json'; | ||||||
| import * as TestNoEthRecipient from '../test/generated-artifacts/TestNoEthRecipient.json'; | import * as TestNoEthRecipient from '../test/generated-artifacts/TestNoEthRecipient.json'; | ||||||
| import * as TestOrderSignerRegistryWithContractWallet from '../test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json'; | import * as TestOrderSignerRegistryWithContractWallet from '../test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json'; | ||||||
| import * as TestPermissionlessTransformerDeployerSuicidal from '../test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json'; | import * as TestPermissionlessTransformerDeployerSuicidal from '../test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json'; | ||||||
| import * as TestPermissionlessTransformerDeployerTransformer from '../test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json'; | import * as TestPermissionlessTransformerDeployerTransformer from '../test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json'; | ||||||
|  | import * as TestPropertyValidator from '../test/generated-artifacts/TestPropertyValidator.json'; | ||||||
| import * as TestRfqOriginRegistration from '../test/generated-artifacts/TestRfqOriginRegistration.json'; | import * as TestRfqOriginRegistration from '../test/generated-artifacts/TestRfqOriginRegistration.json'; | ||||||
| import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json'; | import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json'; | ||||||
| import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json'; | import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json'; | ||||||
| @@ -183,6 +217,7 @@ export const artifacts = { | |||||||
|     LibCommonRichErrors: LibCommonRichErrors as ContractArtifact, |     LibCommonRichErrors: LibCommonRichErrors as ContractArtifact, | ||||||
|     LibLiquidityProviderRichErrors: LibLiquidityProviderRichErrors as ContractArtifact, |     LibLiquidityProviderRichErrors: LibLiquidityProviderRichErrors as ContractArtifact, | ||||||
|     LibMetaTransactionsRichErrors: LibMetaTransactionsRichErrors as ContractArtifact, |     LibMetaTransactionsRichErrors: LibMetaTransactionsRichErrors as ContractArtifact, | ||||||
|  |     LibNFTOrdersRichErrors: LibNFTOrdersRichErrors as ContractArtifact, | ||||||
|     LibNativeOrdersRichErrors: LibNativeOrdersRichErrors as ContractArtifact, |     LibNativeOrdersRichErrors: LibNativeOrdersRichErrors as ContractArtifact, | ||||||
|     LibOwnableRichErrors: LibOwnableRichErrors as ContractArtifact, |     LibOwnableRichErrors: LibOwnableRichErrors as ContractArtifact, | ||||||
|     LibProxyRichErrors: LibProxyRichErrors as ContractArtifact, |     LibProxyRichErrors: LibProxyRichErrors as ContractArtifact, | ||||||
| @@ -201,6 +236,7 @@ export const artifacts = { | |||||||
|     TransformerDeployer: TransformerDeployer as ContractArtifact, |     TransformerDeployer: TransformerDeployer as ContractArtifact, | ||||||
|     BatchFillNativeOrdersFeature: BatchFillNativeOrdersFeature as ContractArtifact, |     BatchFillNativeOrdersFeature: BatchFillNativeOrdersFeature as ContractArtifact, | ||||||
|     BootstrapFeature: BootstrapFeature as ContractArtifact, |     BootstrapFeature: BootstrapFeature as ContractArtifact, | ||||||
|  |     ERC165Feature: ERC165Feature as ContractArtifact, | ||||||
|     FundRecoveryFeature: FundRecoveryFeature as ContractArtifact, |     FundRecoveryFeature: FundRecoveryFeature as ContractArtifact, | ||||||
|     LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact, |     LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact, | ||||||
|     MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact, |     MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact, | ||||||
| @@ -214,6 +250,9 @@ export const artifacts = { | |||||||
|     UniswapV3Feature: UniswapV3Feature as ContractArtifact, |     UniswapV3Feature: UniswapV3Feature as ContractArtifact, | ||||||
|     IBatchFillNativeOrdersFeature: IBatchFillNativeOrdersFeature as ContractArtifact, |     IBatchFillNativeOrdersFeature: IBatchFillNativeOrdersFeature as ContractArtifact, | ||||||
|     IBootstrapFeature: IBootstrapFeature as ContractArtifact, |     IBootstrapFeature: IBootstrapFeature as ContractArtifact, | ||||||
|  |     IERC1155OrdersFeature: IERC1155OrdersFeature as ContractArtifact, | ||||||
|  |     IERC165Feature: IERC165Feature as ContractArtifact, | ||||||
|  |     IERC721OrdersFeature: IERC721OrdersFeature as ContractArtifact, | ||||||
|     IFeature: IFeature as ContractArtifact, |     IFeature: IFeature as ContractArtifact, | ||||||
|     IFundRecoveryFeature: IFundRecoveryFeature as ContractArtifact, |     IFundRecoveryFeature: IFundRecoveryFeature as ContractArtifact, | ||||||
|     ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact, |     ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact, | ||||||
| @@ -229,6 +268,7 @@ export const artifacts = { | |||||||
|     ITransformERC20Feature: ITransformERC20Feature as ContractArtifact, |     ITransformERC20Feature: ITransformERC20Feature as ContractArtifact, | ||||||
|     IUniswapFeature: IUniswapFeature as ContractArtifact, |     IUniswapFeature: IUniswapFeature as ContractArtifact, | ||||||
|     IUniswapV3Feature: IUniswapV3Feature as ContractArtifact, |     IUniswapV3Feature: IUniswapV3Feature as ContractArtifact, | ||||||
|  |     LibNFTOrder: LibNFTOrder as ContractArtifact, | ||||||
|     LibNativeOrder: LibNativeOrder as ContractArtifact, |     LibNativeOrder: LibNativeOrder as ContractArtifact, | ||||||
|     LibSignature: LibSignature as ContractArtifact, |     LibSignature: LibSignature as ContractArtifact, | ||||||
|     MultiplexFeature: MultiplexFeature as ContractArtifact, |     MultiplexFeature: MultiplexFeature as ContractArtifact, | ||||||
| @@ -242,8 +282,13 @@ export const artifacts = { | |||||||
|     NativeOrdersInfo: NativeOrdersInfo as ContractArtifact, |     NativeOrdersInfo: NativeOrdersInfo as ContractArtifact, | ||||||
|     NativeOrdersProtocolFees: NativeOrdersProtocolFees as ContractArtifact, |     NativeOrdersProtocolFees: NativeOrdersProtocolFees as ContractArtifact, | ||||||
|     NativeOrdersSettlement: NativeOrdersSettlement as ContractArtifact, |     NativeOrdersSettlement: NativeOrdersSettlement as ContractArtifact, | ||||||
|  |     ERC1155OrdersFeature: ERC1155OrdersFeature as ContractArtifact, | ||||||
|  |     ERC721OrdersFeature: ERC721OrdersFeature as ContractArtifact, | ||||||
|  |     NFTOrders: NFTOrders as ContractArtifact, | ||||||
|     FixinCommon: FixinCommon as ContractArtifact, |     FixinCommon: FixinCommon as ContractArtifact, | ||||||
|     FixinEIP712: FixinEIP712 as ContractArtifact, |     FixinEIP712: FixinEIP712 as ContractArtifact, | ||||||
|  |     FixinERC1155Spender: FixinERC1155Spender as ContractArtifact, | ||||||
|  |     FixinERC721Spender: FixinERC721Spender as ContractArtifact, | ||||||
|     FixinProtocolFees: FixinProtocolFees as ContractArtifact, |     FixinProtocolFees: FixinProtocolFees as ContractArtifact, | ||||||
|     FixinReentrancyGuard: FixinReentrancyGuard as ContractArtifact, |     FixinReentrancyGuard: FixinReentrancyGuard as ContractArtifact, | ||||||
|     FixinTokenSpender: FixinTokenSpender as ContractArtifact, |     FixinTokenSpender: FixinTokenSpender as ContractArtifact, | ||||||
| @@ -253,6 +298,8 @@ export const artifacts = { | |||||||
|     InitialMigration: InitialMigration as ContractArtifact, |     InitialMigration: InitialMigration as ContractArtifact, | ||||||
|     LibBootstrap: LibBootstrap as ContractArtifact, |     LibBootstrap: LibBootstrap as ContractArtifact, | ||||||
|     LibMigrate: LibMigrate as ContractArtifact, |     LibMigrate: LibMigrate as ContractArtifact, | ||||||
|  |     LibERC1155OrdersStorage: LibERC1155OrdersStorage as ContractArtifact, | ||||||
|  |     LibERC721OrdersStorage: LibERC721OrdersStorage as ContractArtifact, | ||||||
|     LibMetaTransactionsStorage: LibMetaTransactionsStorage as ContractArtifact, |     LibMetaTransactionsStorage: LibMetaTransactionsStorage as ContractArtifact, | ||||||
|     LibNativeOrdersStorage: LibNativeOrdersStorage as ContractArtifact, |     LibNativeOrdersStorage: LibNativeOrdersStorage as ContractArtifact, | ||||||
|     LibOtcOrdersStorage: LibOtcOrdersStorage as ContractArtifact, |     LibOtcOrdersStorage: LibOtcOrdersStorage as ContractArtifact, | ||||||
| @@ -271,35 +318,51 @@ export const artifacts = { | |||||||
|     PositiveSlippageFeeTransformer: PositiveSlippageFeeTransformer as ContractArtifact, |     PositiveSlippageFeeTransformer: PositiveSlippageFeeTransformer as ContractArtifact, | ||||||
|     Transformer: Transformer as ContractArtifact, |     Transformer: Transformer as ContractArtifact, | ||||||
|     WethTransformer: WethTransformer as ContractArtifact, |     WethTransformer: WethTransformer as ContractArtifact, | ||||||
|     BridgeAdapter: BridgeAdapter as ContractArtifact, |     AbstractBridgeAdapter: AbstractBridgeAdapter as ContractArtifact, | ||||||
|  |     AvalancheBridgeAdapter: AvalancheBridgeAdapter as ContractArtifact, | ||||||
|  |     BSCBridgeAdapter: BSCBridgeAdapter as ContractArtifact, | ||||||
|     BridgeProtocols: BridgeProtocols as ContractArtifact, |     BridgeProtocols: BridgeProtocols as ContractArtifact, | ||||||
|  |     CeloBridgeAdapter: CeloBridgeAdapter as ContractArtifact, | ||||||
|  |     EthereumBridgeAdapter: EthereumBridgeAdapter as ContractArtifact, | ||||||
|  |     FantomBridgeAdapter: FantomBridgeAdapter as ContractArtifact, | ||||||
|     IBridgeAdapter: IBridgeAdapter as ContractArtifact, |     IBridgeAdapter: IBridgeAdapter as ContractArtifact, | ||||||
|  |     OptimismBridgeAdapter: OptimismBridgeAdapter as ContractArtifact, | ||||||
|  |     PolygonBridgeAdapter: PolygonBridgeAdapter as ContractArtifact, | ||||||
|     MixinAaveV2: MixinAaveV2 as ContractArtifact, |     MixinAaveV2: MixinAaveV2 as ContractArtifact, | ||||||
|     MixinBalancer: MixinBalancer as ContractArtifact, |     MixinBalancer: MixinBalancer as ContractArtifact, | ||||||
|     MixinBalancerV2: MixinBalancerV2 as ContractArtifact, |     MixinBalancerV2: MixinBalancerV2 as ContractArtifact, | ||||||
|  |     MixinBalancerV2Batch: MixinBalancerV2Batch as ContractArtifact, | ||||||
|     MixinBancor: MixinBancor as ContractArtifact, |     MixinBancor: MixinBancor as ContractArtifact, | ||||||
|     MixinCoFiX: MixinCoFiX as ContractArtifact, |     MixinBancorV3: MixinBancorV3 as ContractArtifact, | ||||||
|     MixinCompound: MixinCompound as ContractArtifact, |     MixinCompound: MixinCompound as ContractArtifact, | ||||||
|     MixinCryptoCom: MixinCryptoCom as ContractArtifact, |     MixinCryptoCom: MixinCryptoCom as ContractArtifact, | ||||||
|     MixinCurve: MixinCurve as ContractArtifact, |     MixinCurve: MixinCurve as ContractArtifact, | ||||||
|     MixinCurveV2: MixinCurveV2 as ContractArtifact, |     MixinCurveV2: MixinCurveV2 as ContractArtifact, | ||||||
|     MixinDodo: MixinDodo as ContractArtifact, |     MixinDodo: MixinDodo as ContractArtifact, | ||||||
|     MixinDodoV2: MixinDodoV2 as ContractArtifact, |     MixinDodoV2: MixinDodoV2 as ContractArtifact, | ||||||
|     MixinKyber: MixinKyber as ContractArtifact, |     MixinGMX: MixinGMX as ContractArtifact, | ||||||
|     MixinKyberDmm: MixinKyberDmm as ContractArtifact, |     MixinKyberDmm: MixinKyberDmm as ContractArtifact, | ||||||
|     MixinLido: MixinLido as ContractArtifact, |     MixinLido: MixinLido as ContractArtifact, | ||||||
|     MixinMStable: MixinMStable as ContractArtifact, |     MixinMStable: MixinMStable as ContractArtifact, | ||||||
|     MixinMakerPSM: MixinMakerPSM as ContractArtifact, |     MixinMakerPSM: MixinMakerPSM as ContractArtifact, | ||||||
|     MixinMooniswap: MixinMooniswap as ContractArtifact, |     MixinMooniswap: MixinMooniswap as ContractArtifact, | ||||||
|     MixinNerve: MixinNerve as ContractArtifact, |     MixinNerve: MixinNerve as ContractArtifact, | ||||||
|     MixinOasis: MixinOasis as ContractArtifact, |     MixinPlatypus: MixinPlatypus as ContractArtifact, | ||||||
|     MixinShell: MixinShell as ContractArtifact, |     MixinShell: MixinShell as ContractArtifact, | ||||||
|  |     MixinSynthetix: MixinSynthetix as ContractArtifact, | ||||||
|     MixinUniswap: MixinUniswap as ContractArtifact, |     MixinUniswap: MixinUniswap as ContractArtifact, | ||||||
|     MixinUniswapV2: MixinUniswapV2 as ContractArtifact, |     MixinUniswapV2: MixinUniswapV2 as ContractArtifact, | ||||||
|     MixinUniswapV3: MixinUniswapV3 as ContractArtifact, |     MixinUniswapV3: MixinUniswapV3 as ContractArtifact, | ||||||
|  |     MixinVelodrome: MixinVelodrome as ContractArtifact, | ||||||
|  |     MixinWOOFi: MixinWOOFi as ContractArtifact, | ||||||
|     MixinZeroExBridge: MixinZeroExBridge as ContractArtifact, |     MixinZeroExBridge: MixinZeroExBridge as ContractArtifact, | ||||||
|  |     IERC1155Token: IERC1155Token as ContractArtifact, | ||||||
|  |     IERC721Token: IERC721Token as ContractArtifact, | ||||||
|  |     IFeeRecipient: IFeeRecipient as ContractArtifact, | ||||||
|     ILiquidityProvider: ILiquidityProvider as ContractArtifact, |     ILiquidityProvider: ILiquidityProvider as ContractArtifact, | ||||||
|     IMooniswapPool: IMooniswapPool as ContractArtifact, |     IMooniswapPool: IMooniswapPool as ContractArtifact, | ||||||
|  |     IPropertyValidator: IPropertyValidator as ContractArtifact, | ||||||
|  |     ITakerCallback: ITakerCallback as ContractArtifact, | ||||||
|     IUniswapV2Pair: IUniswapV2Pair as ContractArtifact, |     IUniswapV2Pair: IUniswapV2Pair as ContractArtifact, | ||||||
|     IUniswapV3Pool: IUniswapV3Pool as ContractArtifact, |     IUniswapV3Pool: IUniswapV3Pool as ContractArtifact, | ||||||
|     IERC20Bridge: IERC20Bridge as ContractArtifact, |     IERC20Bridge: IERC20Bridge as ContractArtifact, | ||||||
| @@ -307,9 +370,9 @@ export const artifacts = { | |||||||
|     ITestSimpleFunctionRegistryFeature: ITestSimpleFunctionRegistryFeature as ContractArtifact, |     ITestSimpleFunctionRegistryFeature: ITestSimpleFunctionRegistryFeature as ContractArtifact, | ||||||
|     TestBridge: TestBridge as ContractArtifact, |     TestBridge: TestBridge as ContractArtifact, | ||||||
|     TestCallTarget: TestCallTarget as ContractArtifact, |     TestCallTarget: TestCallTarget as ContractArtifact, | ||||||
|     TestCurve: TestCurve as ContractArtifact, |  | ||||||
|     TestDelegateCaller: TestDelegateCaller as ContractArtifact, |     TestDelegateCaller: TestDelegateCaller as ContractArtifact, | ||||||
|     TestFeeCollectorController: TestFeeCollectorController as ContractArtifact, |     TestFeeCollectorController: TestFeeCollectorController as ContractArtifact, | ||||||
|  |     TestFeeRecipient: TestFeeRecipient as ContractArtifact, | ||||||
|     TestFillQuoteTransformerBridge: TestFillQuoteTransformerBridge as ContractArtifact, |     TestFillQuoteTransformerBridge: TestFillQuoteTransformerBridge as ContractArtifact, | ||||||
|     TestFillQuoteTransformerExchange: TestFillQuoteTransformerExchange as ContractArtifact, |     TestFillQuoteTransformerExchange: TestFillQuoteTransformerExchange as ContractArtifact, | ||||||
|     TestFillQuoteTransformerHost: TestFillQuoteTransformerHost as ContractArtifact, |     TestFillQuoteTransformerHost: TestFillQuoteTransformerHost as ContractArtifact, | ||||||
| @@ -319,33 +382,38 @@ export const artifacts = { | |||||||
|     TestInitialMigration: TestInitialMigration as ContractArtifact, |     TestInitialMigration: TestInitialMigration as ContractArtifact, | ||||||
|     TestLibNativeOrder: TestLibNativeOrder as ContractArtifact, |     TestLibNativeOrder: TestLibNativeOrder as ContractArtifact, | ||||||
|     TestLibSignature: TestLibSignature as ContractArtifact, |     TestLibSignature: TestLibSignature as ContractArtifact, | ||||||
|     TestLiquidityProvider: TestLiquidityProvider as ContractArtifact, |  | ||||||
|     TestMetaTransactionsNativeOrdersFeature: TestMetaTransactionsNativeOrdersFeature as ContractArtifact, |     TestMetaTransactionsNativeOrdersFeature: TestMetaTransactionsNativeOrdersFeature as ContractArtifact, | ||||||
|     TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact, |     TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact, | ||||||
|     TestMigrator: TestMigrator as ContractArtifact, |     TestMigrator: TestMigrator as ContractArtifact, | ||||||
|     TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact, |     TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact, | ||||||
|     TestMintableERC20Token: TestMintableERC20Token as ContractArtifact, |     TestNFTOrderPresigner: TestNFTOrderPresigner as ContractArtifact, | ||||||
|     TestMooniswap: TestMooniswap as ContractArtifact, |  | ||||||
|     TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact, |     TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact, | ||||||
|     TestNoEthRecipient: TestNoEthRecipient as ContractArtifact, |     TestNoEthRecipient: TestNoEthRecipient as ContractArtifact, | ||||||
|     TestOrderSignerRegistryWithContractWallet: TestOrderSignerRegistryWithContractWallet as ContractArtifact, |     TestOrderSignerRegistryWithContractWallet: TestOrderSignerRegistryWithContractWallet as ContractArtifact, | ||||||
|     TestPermissionlessTransformerDeployerSuicidal: TestPermissionlessTransformerDeployerSuicidal as ContractArtifact, |     TestPermissionlessTransformerDeployerSuicidal: TestPermissionlessTransformerDeployerSuicidal as ContractArtifact, | ||||||
|     TestPermissionlessTransformerDeployerTransformer: TestPermissionlessTransformerDeployerTransformer as ContractArtifact, |     TestPermissionlessTransformerDeployerTransformer: TestPermissionlessTransformerDeployerTransformer as ContractArtifact, | ||||||
|  |     TestPropertyValidator: TestPropertyValidator as ContractArtifact, | ||||||
|     TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact, |     TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact, | ||||||
|     TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact, |     TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact, | ||||||
|     TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 as ContractArtifact, |     TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 as ContractArtifact, | ||||||
|     TestStaking: TestStaking as ContractArtifact, |     TestStaking: TestStaking as ContractArtifact, | ||||||
|     TestTokenSpenderERC20Token: TestTokenSpenderERC20Token as ContractArtifact, |  | ||||||
|     TestTransformERC20: TestTransformERC20 as ContractArtifact, |     TestTransformERC20: TestTransformERC20 as ContractArtifact, | ||||||
|     TestTransformerBase: TestTransformerBase as ContractArtifact, |     TestTransformerBase: TestTransformerBase as ContractArtifact, | ||||||
|     TestTransformerDeployerTransformer: TestTransformerDeployerTransformer as ContractArtifact, |     TestTransformerDeployerTransformer: TestTransformerDeployerTransformer as ContractArtifact, | ||||||
|     TestTransformerHost: TestTransformerHost as ContractArtifact, |     TestTransformerHost: TestTransformerHost as ContractArtifact, | ||||||
|  |     TestUniswapV3Feature: TestUniswapV3Feature as ContractArtifact, | ||||||
|  |     TestWethTransformerHost: TestWethTransformerHost as ContractArtifact, | ||||||
|  |     TestZeroExFeature: TestZeroExFeature as ContractArtifact, | ||||||
|  |     TestCurve: TestCurve as ContractArtifact, | ||||||
|  |     TestLiquidityProvider: TestLiquidityProvider as ContractArtifact, | ||||||
|  |     TestMooniswap: TestMooniswap as ContractArtifact, | ||||||
|     TestUniswapV2Factory: TestUniswapV2Factory as ContractArtifact, |     TestUniswapV2Factory: TestUniswapV2Factory as ContractArtifact, | ||||||
|     TestUniswapV2Pool: TestUniswapV2Pool as ContractArtifact, |     TestUniswapV2Pool: TestUniswapV2Pool as ContractArtifact, | ||||||
|     TestUniswapV3Factory: TestUniswapV3Factory as ContractArtifact, |     TestUniswapV3Factory: TestUniswapV3Factory as ContractArtifact, | ||||||
|     TestUniswapV3Feature: TestUniswapV3Feature as ContractArtifact, |  | ||||||
|     TestUniswapV3Pool: TestUniswapV3Pool as ContractArtifact, |     TestUniswapV3Pool: TestUniswapV3Pool as ContractArtifact, | ||||||
|  |     TestMintableERC1155Token: TestMintableERC1155Token as ContractArtifact, | ||||||
|  |     TestMintableERC20Token: TestMintableERC20Token as ContractArtifact, | ||||||
|  |     TestMintableERC721Token: TestMintableERC721Token as ContractArtifact, | ||||||
|  |     TestTokenSpenderERC20Token: TestTokenSpenderERC20Token as ContractArtifact, | ||||||
|     TestWeth: TestWeth as ContractArtifact, |     TestWeth: TestWeth as ContractArtifact, | ||||||
|     TestWethTransformerHost: TestWethTransformerHost as ContractArtifact, |  | ||||||
|     TestZeroExFeature: TestZeroExFeature as ContractArtifact, |  | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										1612
									
								
								contracts/zero-ex/test/features/erc1155_orders_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1612
									
								
								contracts/zero-ex/test/features/erc1155_orders_test.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1731
									
								
								contracts/zero-ex/test/features/erc721_orders_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1731
									
								
								contracts/zero-ex/test/features/erc721_orders_test.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -28,7 +28,7 @@ import { artifacts } from '../artifacts'; | |||||||
| import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge'; | import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge'; | ||||||
| import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders'; | import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders'; | ||||||
| import { | import { | ||||||
|     BridgeAdapterContract, |     EthereumBridgeAdapterContract, | ||||||
|     FillQuoteTransformerContract, |     FillQuoteTransformerContract, | ||||||
|     TestFillQuoteTransformerExchangeContract, |     TestFillQuoteTransformerExchangeContract, | ||||||
|     TestFillQuoteTransformerHostContract, |     TestFillQuoteTransformerHostContract, | ||||||
| @@ -52,7 +52,8 @@ blockchainTests.resets('FillQuoteTransformer', env => { | |||||||
|     let singleProtocolFee: BigNumber; |     let singleProtocolFee: BigNumber; | ||||||
|  |  | ||||||
|     const GAS_PRICE = 1337; |     const GAS_PRICE = 1337; | ||||||
|     const TEST_BRIDGE_SOURCE = hexUtils.random(32); |     // Left half is 0, corresponding to BridgeProtocol.Unknown | ||||||
|  |     const TEST_BRIDGE_SOURCE = hexUtils.leftPad(hexUtils.random(16), 32); | ||||||
|     const HIGH_BIT = new BigNumber(2).pow(255); |     const HIGH_BIT = new BigNumber(2).pow(255); | ||||||
|     const REVERT_AMOUNT = new BigNumber('0xdeadbeef'); |     const REVERT_AMOUNT = new BigNumber('0xdeadbeef'); | ||||||
|  |  | ||||||
| @@ -64,8 +65,8 @@ blockchainTests.resets('FillQuoteTransformer', env => { | |||||||
|             env.txDefaults, |             env.txDefaults, | ||||||
|             artifacts, |             artifacts, | ||||||
|         ); |         ); | ||||||
|         const bridgeAdapter = await BridgeAdapterContract.deployFrom0xArtifactAsync( |         const bridgeAdapter = await EthereumBridgeAdapterContract.deployFrom0xArtifactAsync( | ||||||
|             artifacts.BridgeAdapter, |             artifacts.EthereumBridgeAdapter, | ||||||
|             env.provider, |             env.provider, | ||||||
|             env.txDefaults, |             env.txDefaults, | ||||||
|             artifacts, |             artifacts, | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								contracts/zero-ex/test/utils/nft_orders.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								contracts/zero-ex/test/utils/nft_orders.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | import { constants, getRandomInteger, randomAddress } from '@0x/contracts-test-utils'; | ||||||
|  | import { ERC1155Order, ERC721Order } from '@0x/protocol-utils'; | ||||||
|  | import { BigNumber } from '@0x/utils'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Generate a random ERC721 Order | ||||||
|  |  */ | ||||||
|  | export function getRandomERC721Order(fields: Partial<ERC721Order> = {}): ERC721Order { | ||||||
|  |     return new ERC721Order({ | ||||||
|  |         erc20Token: randomAddress(), | ||||||
|  |         erc20TokenAmount: getRandomInteger('1e18', '10e18'), | ||||||
|  |         erc721Token: randomAddress(), | ||||||
|  |         erc721TokenId: getRandomInteger(0, constants.MAX_UINT256), | ||||||
|  |         maker: randomAddress(), | ||||||
|  |         taker: randomAddress(), | ||||||
|  |         erc721TokenProperties: [], | ||||||
|  |         fees: [], | ||||||
|  |         nonce: getRandomInteger(0, constants.MAX_UINT256), | ||||||
|  |         expiry: new BigNumber(Math.floor(Date.now() / 1000 + 60)), | ||||||
|  |         ...fields, | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * Generate a random ERC1155 Order | ||||||
|  |  */ | ||||||
|  | export function getRandomERC1155Order(fields: Partial<ERC1155Order> = {}): ERC1155Order { | ||||||
|  |     return new ERC1155Order({ | ||||||
|  |         erc20Token: randomAddress(), | ||||||
|  |         erc20TokenAmount: getRandomInteger('1e18', '10e18'), | ||||||
|  |         erc1155Token: randomAddress(), | ||||||
|  |         erc1155TokenId: getRandomInteger(0, constants.MAX_UINT256), | ||||||
|  |         erc1155TokenAmount: getRandomInteger(1, '10e18'), | ||||||
|  |         maker: randomAddress(), | ||||||
|  |         taker: randomAddress(), | ||||||
|  |         erc1155TokenProperties: [], | ||||||
|  |         fees: [], | ||||||
|  |         nonce: getRandomInteger(0, constants.MAX_UINT256), | ||||||
|  |         expiry: new BigNumber(Math.floor(Date.now() / 1000 + 60)), | ||||||
|  |         ...fields, | ||||||
|  |     }); | ||||||
|  | } | ||||||
| @@ -3,17 +3,27 @@ | |||||||
|  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. |  * Warning: This file is auto-generated by contracts-gen. Don't edit manually. | ||||||
|  * ----------------------------------------------------------------------------- |  * ----------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
|  | export * from '../test/generated-wrappers/abstract_bridge_adapter'; | ||||||
| export * from '../test/generated-wrappers/affiliate_fee_transformer'; | export * from '../test/generated-wrappers/affiliate_fee_transformer'; | ||||||
|  | export * from '../test/generated-wrappers/avalanche_bridge_adapter'; | ||||||
|  | export * from '../test/generated-wrappers/b_s_c_bridge_adapter'; | ||||||
| export * from '../test/generated-wrappers/batch_fill_native_orders_feature'; | export * from '../test/generated-wrappers/batch_fill_native_orders_feature'; | ||||||
| export * from '../test/generated-wrappers/bootstrap_feature'; | export * from '../test/generated-wrappers/bootstrap_feature'; | ||||||
| export * from '../test/generated-wrappers/bridge_adapter'; |  | ||||||
| export * from '../test/generated-wrappers/bridge_protocols'; | export * from '../test/generated-wrappers/bridge_protocols'; | ||||||
|  | export * from '../test/generated-wrappers/celo_bridge_adapter'; | ||||||
| export * from '../test/generated-wrappers/curve_liquidity_provider'; | export * from '../test/generated-wrappers/curve_liquidity_provider'; | ||||||
|  | export * from '../test/generated-wrappers/erc1155_orders_feature'; | ||||||
|  | export * from '../test/generated-wrappers/erc165_feature'; | ||||||
|  | export * from '../test/generated-wrappers/erc721_orders_feature'; | ||||||
|  | export * from '../test/generated-wrappers/ethereum_bridge_adapter'; | ||||||
|  | export * from '../test/generated-wrappers/fantom_bridge_adapter'; | ||||||
| export * from '../test/generated-wrappers/fee_collector'; | export * from '../test/generated-wrappers/fee_collector'; | ||||||
| export * from '../test/generated-wrappers/fee_collector_controller'; | export * from '../test/generated-wrappers/fee_collector_controller'; | ||||||
| export * from '../test/generated-wrappers/fill_quote_transformer'; | export * from '../test/generated-wrappers/fill_quote_transformer'; | ||||||
| export * from '../test/generated-wrappers/fixin_common'; | export * from '../test/generated-wrappers/fixin_common'; | ||||||
| export * from '../test/generated-wrappers/fixin_e_i_p712'; | export * from '../test/generated-wrappers/fixin_e_i_p712'; | ||||||
|  | export * from '../test/generated-wrappers/fixin_erc1155_spender'; | ||||||
|  | export * from '../test/generated-wrappers/fixin_erc721_spender'; | ||||||
| export * from '../test/generated-wrappers/fixin_protocol_fees'; | export * from '../test/generated-wrappers/fixin_protocol_fees'; | ||||||
| export * from '../test/generated-wrappers/fixin_reentrancy_guard'; | export * from '../test/generated-wrappers/fixin_reentrancy_guard'; | ||||||
| export * from '../test/generated-wrappers/fixin_token_spender'; | export * from '../test/generated-wrappers/fixin_token_spender'; | ||||||
| @@ -23,9 +33,15 @@ export * from '../test/generated-wrappers/fund_recovery_feature'; | |||||||
| export * from '../test/generated-wrappers/i_batch_fill_native_orders_feature'; | export * from '../test/generated-wrappers/i_batch_fill_native_orders_feature'; | ||||||
| export * from '../test/generated-wrappers/i_bootstrap_feature'; | export * from '../test/generated-wrappers/i_bootstrap_feature'; | ||||||
| export * from '../test/generated-wrappers/i_bridge_adapter'; | export * from '../test/generated-wrappers/i_bridge_adapter'; | ||||||
|  | export * from '../test/generated-wrappers/i_erc1155_orders_feature'; | ||||||
|  | export * from '../test/generated-wrappers/i_erc1155_token'; | ||||||
|  | export * from '../test/generated-wrappers/i_erc165_feature'; | ||||||
| export * from '../test/generated-wrappers/i_erc20_bridge'; | export * from '../test/generated-wrappers/i_erc20_bridge'; | ||||||
| export * from '../test/generated-wrappers/i_erc20_transformer'; | export * from '../test/generated-wrappers/i_erc20_transformer'; | ||||||
|  | export * from '../test/generated-wrappers/i_erc721_orders_feature'; | ||||||
|  | export * from '../test/generated-wrappers/i_erc721_token'; | ||||||
| export * from '../test/generated-wrappers/i_feature'; | export * from '../test/generated-wrappers/i_feature'; | ||||||
|  | export * from '../test/generated-wrappers/i_fee_recipient'; | ||||||
| export * from '../test/generated-wrappers/i_flash_wallet'; | export * from '../test/generated-wrappers/i_flash_wallet'; | ||||||
| export * from '../test/generated-wrappers/i_fund_recovery_feature'; | export * from '../test/generated-wrappers/i_fund_recovery_feature'; | ||||||
| export * from '../test/generated-wrappers/i_liquidity_provider'; | export * from '../test/generated-wrappers/i_liquidity_provider'; | ||||||
| @@ -39,8 +55,10 @@ export * from '../test/generated-wrappers/i_native_orders_feature'; | |||||||
| export * from '../test/generated-wrappers/i_otc_orders_feature'; | export * from '../test/generated-wrappers/i_otc_orders_feature'; | ||||||
| export * from '../test/generated-wrappers/i_ownable_feature'; | export * from '../test/generated-wrappers/i_ownable_feature'; | ||||||
| export * from '../test/generated-wrappers/i_pancake_swap_feature'; | export * from '../test/generated-wrappers/i_pancake_swap_feature'; | ||||||
|  | export * from '../test/generated-wrappers/i_property_validator'; | ||||||
| export * from '../test/generated-wrappers/i_simple_function_registry_feature'; | export * from '../test/generated-wrappers/i_simple_function_registry_feature'; | ||||||
| export * from '../test/generated-wrappers/i_staking'; | export * from '../test/generated-wrappers/i_staking'; | ||||||
|  | export * from '../test/generated-wrappers/i_taker_callback'; | ||||||
| export * from '../test/generated-wrappers/i_test_simple_function_registry_feature'; | export * from '../test/generated-wrappers/i_test_simple_function_registry_feature'; | ||||||
| export * from '../test/generated-wrappers/i_token_spender_feature'; | export * from '../test/generated-wrappers/i_token_spender_feature'; | ||||||
| export * from '../test/generated-wrappers/i_transform_erc20_feature'; | export * from '../test/generated-wrappers/i_transform_erc20_feature'; | ||||||
| @@ -52,12 +70,16 @@ export * from '../test/generated-wrappers/i_zero_ex'; | |||||||
| export * from '../test/generated-wrappers/initial_migration'; | export * from '../test/generated-wrappers/initial_migration'; | ||||||
| export * from '../test/generated-wrappers/lib_bootstrap'; | export * from '../test/generated-wrappers/lib_bootstrap'; | ||||||
| export * from '../test/generated-wrappers/lib_common_rich_errors'; | export * from '../test/generated-wrappers/lib_common_rich_errors'; | ||||||
|  | export * from '../test/generated-wrappers/lib_erc1155_orders_storage'; | ||||||
| export * from '../test/generated-wrappers/lib_erc20_transformer'; | export * from '../test/generated-wrappers/lib_erc20_transformer'; | ||||||
|  | export * from '../test/generated-wrappers/lib_erc721_orders_storage'; | ||||||
| export * from '../test/generated-wrappers/lib_fee_collector'; | export * from '../test/generated-wrappers/lib_fee_collector'; | ||||||
| export * from '../test/generated-wrappers/lib_liquidity_provider_rich_errors'; | export * from '../test/generated-wrappers/lib_liquidity_provider_rich_errors'; | ||||||
| export * from '../test/generated-wrappers/lib_meta_transactions_rich_errors'; | export * from '../test/generated-wrappers/lib_meta_transactions_rich_errors'; | ||||||
| export * from '../test/generated-wrappers/lib_meta_transactions_storage'; | export * from '../test/generated-wrappers/lib_meta_transactions_storage'; | ||||||
| export * from '../test/generated-wrappers/lib_migrate'; | export * from '../test/generated-wrappers/lib_migrate'; | ||||||
|  | export * from '../test/generated-wrappers/lib_n_f_t_order'; | ||||||
|  | export * from '../test/generated-wrappers/lib_n_f_t_orders_rich_errors'; | ||||||
| export * from '../test/generated-wrappers/lib_native_order'; | export * from '../test/generated-wrappers/lib_native_order'; | ||||||
| export * from '../test/generated-wrappers/lib_native_orders_rich_errors'; | export * from '../test/generated-wrappers/lib_native_orders_rich_errors'; | ||||||
| export * from '../test/generated-wrappers/lib_native_orders_storage'; | export * from '../test/generated-wrappers/lib_native_orders_storage'; | ||||||
| @@ -82,26 +104,30 @@ export * from '../test/generated-wrappers/meta_transactions_feature'; | |||||||
| export * from '../test/generated-wrappers/mixin_aave_v2'; | export * from '../test/generated-wrappers/mixin_aave_v2'; | ||||||
| export * from '../test/generated-wrappers/mixin_balancer'; | export * from '../test/generated-wrappers/mixin_balancer'; | ||||||
| export * from '../test/generated-wrappers/mixin_balancer_v2'; | export * from '../test/generated-wrappers/mixin_balancer_v2'; | ||||||
|  | export * from '../test/generated-wrappers/mixin_balancer_v2_batch'; | ||||||
| export * from '../test/generated-wrappers/mixin_bancor'; | export * from '../test/generated-wrappers/mixin_bancor'; | ||||||
| export * from '../test/generated-wrappers/mixin_co_fi_x'; | export * from '../test/generated-wrappers/mixin_bancor_v3'; | ||||||
| export * from '../test/generated-wrappers/mixin_compound'; | export * from '../test/generated-wrappers/mixin_compound'; | ||||||
| export * from '../test/generated-wrappers/mixin_crypto_com'; | export * from '../test/generated-wrappers/mixin_crypto_com'; | ||||||
| export * from '../test/generated-wrappers/mixin_curve'; | export * from '../test/generated-wrappers/mixin_curve'; | ||||||
| export * from '../test/generated-wrappers/mixin_curve_v2'; | export * from '../test/generated-wrappers/mixin_curve_v2'; | ||||||
| export * from '../test/generated-wrappers/mixin_dodo'; | export * from '../test/generated-wrappers/mixin_dodo'; | ||||||
| export * from '../test/generated-wrappers/mixin_dodo_v2'; | export * from '../test/generated-wrappers/mixin_dodo_v2'; | ||||||
| export * from '../test/generated-wrappers/mixin_kyber'; | export * from '../test/generated-wrappers/mixin_g_m_x'; | ||||||
| export * from '../test/generated-wrappers/mixin_kyber_dmm'; | export * from '../test/generated-wrappers/mixin_kyber_dmm'; | ||||||
| export * from '../test/generated-wrappers/mixin_lido'; | export * from '../test/generated-wrappers/mixin_lido'; | ||||||
| export * from '../test/generated-wrappers/mixin_m_stable'; | export * from '../test/generated-wrappers/mixin_m_stable'; | ||||||
| export * from '../test/generated-wrappers/mixin_maker_p_s_m'; | export * from '../test/generated-wrappers/mixin_maker_p_s_m'; | ||||||
| export * from '../test/generated-wrappers/mixin_mooniswap'; | export * from '../test/generated-wrappers/mixin_mooniswap'; | ||||||
| export * from '../test/generated-wrappers/mixin_nerve'; | export * from '../test/generated-wrappers/mixin_nerve'; | ||||||
| export * from '../test/generated-wrappers/mixin_oasis'; | export * from '../test/generated-wrappers/mixin_platypus'; | ||||||
| export * from '../test/generated-wrappers/mixin_shell'; | export * from '../test/generated-wrappers/mixin_shell'; | ||||||
|  | export * from '../test/generated-wrappers/mixin_synthetix'; | ||||||
| export * from '../test/generated-wrappers/mixin_uniswap'; | export * from '../test/generated-wrappers/mixin_uniswap'; | ||||||
| export * from '../test/generated-wrappers/mixin_uniswap_v2'; | export * from '../test/generated-wrappers/mixin_uniswap_v2'; | ||||||
| export * from '../test/generated-wrappers/mixin_uniswap_v3'; | export * from '../test/generated-wrappers/mixin_uniswap_v3'; | ||||||
|  | export * from '../test/generated-wrappers/mixin_velodrome'; | ||||||
|  | export * from '../test/generated-wrappers/mixin_w_o_o_fi'; | ||||||
| export * from '../test/generated-wrappers/mixin_zero_ex_bridge'; | export * from '../test/generated-wrappers/mixin_zero_ex_bridge'; | ||||||
| export * from '../test/generated-wrappers/mooniswap_liquidity_provider'; | export * from '../test/generated-wrappers/mooniswap_liquidity_provider'; | ||||||
| export * from '../test/generated-wrappers/multiplex_feature'; | export * from '../test/generated-wrappers/multiplex_feature'; | ||||||
| @@ -111,16 +137,19 @@ export * from '../test/generated-wrappers/multiplex_rfq'; | |||||||
| export * from '../test/generated-wrappers/multiplex_transform_erc20'; | export * from '../test/generated-wrappers/multiplex_transform_erc20'; | ||||||
| export * from '../test/generated-wrappers/multiplex_uniswap_v2'; | export * from '../test/generated-wrappers/multiplex_uniswap_v2'; | ||||||
| export * from '../test/generated-wrappers/multiplex_uniswap_v3'; | export * from '../test/generated-wrappers/multiplex_uniswap_v3'; | ||||||
|  | export * from '../test/generated-wrappers/n_f_t_orders'; | ||||||
| export * from '../test/generated-wrappers/native_orders_cancellation'; | export * from '../test/generated-wrappers/native_orders_cancellation'; | ||||||
| export * from '../test/generated-wrappers/native_orders_feature'; | export * from '../test/generated-wrappers/native_orders_feature'; | ||||||
| export * from '../test/generated-wrappers/native_orders_info'; | export * from '../test/generated-wrappers/native_orders_info'; | ||||||
| export * from '../test/generated-wrappers/native_orders_protocol_fees'; | export * from '../test/generated-wrappers/native_orders_protocol_fees'; | ||||||
| export * from '../test/generated-wrappers/native_orders_settlement'; | export * from '../test/generated-wrappers/native_orders_settlement'; | ||||||
|  | export * from '../test/generated-wrappers/optimism_bridge_adapter'; | ||||||
| export * from '../test/generated-wrappers/otc_orders_feature'; | export * from '../test/generated-wrappers/otc_orders_feature'; | ||||||
| export * from '../test/generated-wrappers/ownable_feature'; | export * from '../test/generated-wrappers/ownable_feature'; | ||||||
| export * from '../test/generated-wrappers/pancake_swap_feature'; | export * from '../test/generated-wrappers/pancake_swap_feature'; | ||||||
| export * from '../test/generated-wrappers/pay_taker_transformer'; | export * from '../test/generated-wrappers/pay_taker_transformer'; | ||||||
| export * from '../test/generated-wrappers/permissionless_transformer_deployer'; | export * from '../test/generated-wrappers/permissionless_transformer_deployer'; | ||||||
|  | export * from '../test/generated-wrappers/polygon_bridge_adapter'; | ||||||
| export * from '../test/generated-wrappers/positive_slippage_fee_transformer'; | export * from '../test/generated-wrappers/positive_slippage_fee_transformer'; | ||||||
| export * from '../test/generated-wrappers/simple_function_registry_feature'; | export * from '../test/generated-wrappers/simple_function_registry_feature'; | ||||||
| export * from '../test/generated-wrappers/test_bridge'; | export * from '../test/generated-wrappers/test_bridge'; | ||||||
| @@ -128,6 +157,7 @@ export * from '../test/generated-wrappers/test_call_target'; | |||||||
| export * from '../test/generated-wrappers/test_curve'; | export * from '../test/generated-wrappers/test_curve'; | ||||||
| export * from '../test/generated-wrappers/test_delegate_caller'; | export * from '../test/generated-wrappers/test_delegate_caller'; | ||||||
| export * from '../test/generated-wrappers/test_fee_collector_controller'; | export * from '../test/generated-wrappers/test_fee_collector_controller'; | ||||||
|  | export * from '../test/generated-wrappers/test_fee_recipient'; | ||||||
| export * from '../test/generated-wrappers/test_fill_quote_transformer_bridge'; | export * from '../test/generated-wrappers/test_fill_quote_transformer_bridge'; | ||||||
| export * from '../test/generated-wrappers/test_fill_quote_transformer_exchange'; | export * from '../test/generated-wrappers/test_fill_quote_transformer_exchange'; | ||||||
| export * from '../test/generated-wrappers/test_fill_quote_transformer_host'; | export * from '../test/generated-wrappers/test_fill_quote_transformer_host'; | ||||||
| @@ -142,13 +172,17 @@ export * from '../test/generated-wrappers/test_meta_transactions_native_orders_f | |||||||
| export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature'; | export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature'; | ||||||
| export * from '../test/generated-wrappers/test_migrator'; | export * from '../test/generated-wrappers/test_migrator'; | ||||||
| export * from '../test/generated-wrappers/test_mint_token_erc20_transformer'; | export * from '../test/generated-wrappers/test_mint_token_erc20_transformer'; | ||||||
|  | export * from '../test/generated-wrappers/test_mintable_erc1155_token'; | ||||||
| export * from '../test/generated-wrappers/test_mintable_erc20_token'; | export * from '../test/generated-wrappers/test_mintable_erc20_token'; | ||||||
|  | export * from '../test/generated-wrappers/test_mintable_erc721_token'; | ||||||
| export * from '../test/generated-wrappers/test_mooniswap'; | export * from '../test/generated-wrappers/test_mooniswap'; | ||||||
|  | export * from '../test/generated-wrappers/test_n_f_t_order_presigner'; | ||||||
| export * from '../test/generated-wrappers/test_native_orders_feature'; | export * from '../test/generated-wrappers/test_native_orders_feature'; | ||||||
| export * from '../test/generated-wrappers/test_no_eth_recipient'; | export * from '../test/generated-wrappers/test_no_eth_recipient'; | ||||||
| export * from '../test/generated-wrappers/test_order_signer_registry_with_contract_wallet'; | export * from '../test/generated-wrappers/test_order_signer_registry_with_contract_wallet'; | ||||||
| export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_suicidal'; | export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_suicidal'; | ||||||
| export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_transformer'; | export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_transformer'; | ||||||
|  | export * from '../test/generated-wrappers/test_property_validator'; | ||||||
| export * from '../test/generated-wrappers/test_rfq_origin_registration'; | export * from '../test/generated-wrappers/test_rfq_origin_registration'; | ||||||
| export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1'; | export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1'; | ||||||
| export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2'; | export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2'; | ||||||
|   | |||||||
| @@ -4,9 +4,13 @@ | |||||||
|     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*", "./scripts/**/*"], |     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*", "./scripts/**/*"], | ||||||
|     "files": [ |     "files": [ | ||||||
|         "generated-artifacts/AffiliateFeeTransformer.json", |         "generated-artifacts/AffiliateFeeTransformer.json", | ||||||
|  |         "generated-artifacts/AvalancheBridgeAdapter.json", | ||||||
|  |         "generated-artifacts/BSCBridgeAdapter.json", | ||||||
|         "generated-artifacts/BatchFillNativeOrdersFeature.json", |         "generated-artifacts/BatchFillNativeOrdersFeature.json", | ||||||
|         "generated-artifacts/BridgeAdapter.json", |         "generated-artifacts/CeloBridgeAdapter.json", | ||||||
|         "generated-artifacts/CurveLiquidityProvider.json", |         "generated-artifacts/CurveLiquidityProvider.json", | ||||||
|  |         "generated-artifacts/EthereumBridgeAdapter.json", | ||||||
|  |         "generated-artifacts/FantomBridgeAdapter.json", | ||||||
|         "generated-artifacts/FeeCollector.json", |         "generated-artifacts/FeeCollector.json", | ||||||
|         "generated-artifacts/FeeCollectorController.json", |         "generated-artifacts/FeeCollectorController.json", | ||||||
|         "generated-artifacts/FillQuoteTransformer.json", |         "generated-artifacts/FillQuoteTransformer.json", | ||||||
| @@ -28,25 +32,37 @@ | |||||||
|         "generated-artifacts/MetaTransactionsFeature.json", |         "generated-artifacts/MetaTransactionsFeature.json", | ||||||
|         "generated-artifacts/MultiplexFeature.json", |         "generated-artifacts/MultiplexFeature.json", | ||||||
|         "generated-artifacts/NativeOrdersFeature.json", |         "generated-artifacts/NativeOrdersFeature.json", | ||||||
|  |         "generated-artifacts/OptimismBridgeAdapter.json", | ||||||
|         "generated-artifacts/OtcOrdersFeature.json", |         "generated-artifacts/OtcOrdersFeature.json", | ||||||
|         "generated-artifacts/OwnableFeature.json", |         "generated-artifacts/OwnableFeature.json", | ||||||
|         "generated-artifacts/PayTakerTransformer.json", |         "generated-artifacts/PayTakerTransformer.json", | ||||||
|  |         "generated-artifacts/PolygonBridgeAdapter.json", | ||||||
|         "generated-artifacts/PositiveSlippageFeeTransformer.json", |         "generated-artifacts/PositiveSlippageFeeTransformer.json", | ||||||
|         "generated-artifacts/SimpleFunctionRegistryFeature.json", |         "generated-artifacts/SimpleFunctionRegistryFeature.json", | ||||||
|         "generated-artifacts/TransformERC20Feature.json", |         "generated-artifacts/TransformERC20Feature.json", | ||||||
|         "generated-artifacts/WethTransformer.json", |         "generated-artifacts/WethTransformer.json", | ||||||
|         "generated-artifacts/ZeroEx.json", |         "generated-artifacts/ZeroEx.json", | ||||||
|  |         "test/generated-artifacts/AbstractBridgeAdapter.json", | ||||||
|         "test/generated-artifacts/AffiliateFeeTransformer.json", |         "test/generated-artifacts/AffiliateFeeTransformer.json", | ||||||
|  |         "test/generated-artifacts/AvalancheBridgeAdapter.json", | ||||||
|  |         "test/generated-artifacts/BSCBridgeAdapter.json", | ||||||
|         "test/generated-artifacts/BatchFillNativeOrdersFeature.json", |         "test/generated-artifacts/BatchFillNativeOrdersFeature.json", | ||||||
|         "test/generated-artifacts/BootstrapFeature.json", |         "test/generated-artifacts/BootstrapFeature.json", | ||||||
|         "test/generated-artifacts/BridgeAdapter.json", |  | ||||||
|         "test/generated-artifacts/BridgeProtocols.json", |         "test/generated-artifacts/BridgeProtocols.json", | ||||||
|  |         "test/generated-artifacts/CeloBridgeAdapter.json", | ||||||
|         "test/generated-artifacts/CurveLiquidityProvider.json", |         "test/generated-artifacts/CurveLiquidityProvider.json", | ||||||
|  |         "test/generated-artifacts/ERC1155OrdersFeature.json", | ||||||
|  |         "test/generated-artifacts/ERC165Feature.json", | ||||||
|  |         "test/generated-artifacts/ERC721OrdersFeature.json", | ||||||
|  |         "test/generated-artifacts/EthereumBridgeAdapter.json", | ||||||
|  |         "test/generated-artifacts/FantomBridgeAdapter.json", | ||||||
|         "test/generated-artifacts/FeeCollector.json", |         "test/generated-artifacts/FeeCollector.json", | ||||||
|         "test/generated-artifacts/FeeCollectorController.json", |         "test/generated-artifacts/FeeCollectorController.json", | ||||||
|         "test/generated-artifacts/FillQuoteTransformer.json", |         "test/generated-artifacts/FillQuoteTransformer.json", | ||||||
|         "test/generated-artifacts/FixinCommon.json", |         "test/generated-artifacts/FixinCommon.json", | ||||||
|         "test/generated-artifacts/FixinEIP712.json", |         "test/generated-artifacts/FixinEIP712.json", | ||||||
|  |         "test/generated-artifacts/FixinERC1155Spender.json", | ||||||
|  |         "test/generated-artifacts/FixinERC721Spender.json", | ||||||
|         "test/generated-artifacts/FixinProtocolFees.json", |         "test/generated-artifacts/FixinProtocolFees.json", | ||||||
|         "test/generated-artifacts/FixinReentrancyGuard.json", |         "test/generated-artifacts/FixinReentrancyGuard.json", | ||||||
|         "test/generated-artifacts/FixinTokenSpender.json", |         "test/generated-artifacts/FixinTokenSpender.json", | ||||||
| @@ -56,9 +72,15 @@ | |||||||
|         "test/generated-artifacts/IBatchFillNativeOrdersFeature.json", |         "test/generated-artifacts/IBatchFillNativeOrdersFeature.json", | ||||||
|         "test/generated-artifacts/IBootstrapFeature.json", |         "test/generated-artifacts/IBootstrapFeature.json", | ||||||
|         "test/generated-artifacts/IBridgeAdapter.json", |         "test/generated-artifacts/IBridgeAdapter.json", | ||||||
|  |         "test/generated-artifacts/IERC1155OrdersFeature.json", | ||||||
|  |         "test/generated-artifacts/IERC1155Token.json", | ||||||
|  |         "test/generated-artifacts/IERC165Feature.json", | ||||||
|         "test/generated-artifacts/IERC20Bridge.json", |         "test/generated-artifacts/IERC20Bridge.json", | ||||||
|         "test/generated-artifacts/IERC20Transformer.json", |         "test/generated-artifacts/IERC20Transformer.json", | ||||||
|  |         "test/generated-artifacts/IERC721OrdersFeature.json", | ||||||
|  |         "test/generated-artifacts/IERC721Token.json", | ||||||
|         "test/generated-artifacts/IFeature.json", |         "test/generated-artifacts/IFeature.json", | ||||||
|  |         "test/generated-artifacts/IFeeRecipient.json", | ||||||
|         "test/generated-artifacts/IFlashWallet.json", |         "test/generated-artifacts/IFlashWallet.json", | ||||||
|         "test/generated-artifacts/IFundRecoveryFeature.json", |         "test/generated-artifacts/IFundRecoveryFeature.json", | ||||||
|         "test/generated-artifacts/ILiquidityProvider.json", |         "test/generated-artifacts/ILiquidityProvider.json", | ||||||
| @@ -72,8 +94,10 @@ | |||||||
|         "test/generated-artifacts/IOtcOrdersFeature.json", |         "test/generated-artifacts/IOtcOrdersFeature.json", | ||||||
|         "test/generated-artifacts/IOwnableFeature.json", |         "test/generated-artifacts/IOwnableFeature.json", | ||||||
|         "test/generated-artifacts/IPancakeSwapFeature.json", |         "test/generated-artifacts/IPancakeSwapFeature.json", | ||||||
|  |         "test/generated-artifacts/IPropertyValidator.json", | ||||||
|         "test/generated-artifacts/ISimpleFunctionRegistryFeature.json", |         "test/generated-artifacts/ISimpleFunctionRegistryFeature.json", | ||||||
|         "test/generated-artifacts/IStaking.json", |         "test/generated-artifacts/IStaking.json", | ||||||
|  |         "test/generated-artifacts/ITakerCallback.json", | ||||||
|         "test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json", |         "test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json", | ||||||
|         "test/generated-artifacts/ITokenSpenderFeature.json", |         "test/generated-artifacts/ITokenSpenderFeature.json", | ||||||
|         "test/generated-artifacts/ITransformERC20Feature.json", |         "test/generated-artifacts/ITransformERC20Feature.json", | ||||||
| @@ -85,12 +109,16 @@ | |||||||
|         "test/generated-artifacts/InitialMigration.json", |         "test/generated-artifacts/InitialMigration.json", | ||||||
|         "test/generated-artifacts/LibBootstrap.json", |         "test/generated-artifacts/LibBootstrap.json", | ||||||
|         "test/generated-artifacts/LibCommonRichErrors.json", |         "test/generated-artifacts/LibCommonRichErrors.json", | ||||||
|  |         "test/generated-artifacts/LibERC1155OrdersStorage.json", | ||||||
|         "test/generated-artifacts/LibERC20Transformer.json", |         "test/generated-artifacts/LibERC20Transformer.json", | ||||||
|  |         "test/generated-artifacts/LibERC721OrdersStorage.json", | ||||||
|         "test/generated-artifacts/LibFeeCollector.json", |         "test/generated-artifacts/LibFeeCollector.json", | ||||||
|         "test/generated-artifacts/LibLiquidityProviderRichErrors.json", |         "test/generated-artifacts/LibLiquidityProviderRichErrors.json", | ||||||
|         "test/generated-artifacts/LibMetaTransactionsRichErrors.json", |         "test/generated-artifacts/LibMetaTransactionsRichErrors.json", | ||||||
|         "test/generated-artifacts/LibMetaTransactionsStorage.json", |         "test/generated-artifacts/LibMetaTransactionsStorage.json", | ||||||
|         "test/generated-artifacts/LibMigrate.json", |         "test/generated-artifacts/LibMigrate.json", | ||||||
|  |         "test/generated-artifacts/LibNFTOrder.json", | ||||||
|  |         "test/generated-artifacts/LibNFTOrdersRichErrors.json", | ||||||
|         "test/generated-artifacts/LibNativeOrder.json", |         "test/generated-artifacts/LibNativeOrder.json", | ||||||
|         "test/generated-artifacts/LibNativeOrdersRichErrors.json", |         "test/generated-artifacts/LibNativeOrdersRichErrors.json", | ||||||
|         "test/generated-artifacts/LibNativeOrdersStorage.json", |         "test/generated-artifacts/LibNativeOrdersStorage.json", | ||||||
| @@ -115,26 +143,30 @@ | |||||||
|         "test/generated-artifacts/MixinAaveV2.json", |         "test/generated-artifacts/MixinAaveV2.json", | ||||||
|         "test/generated-artifacts/MixinBalancer.json", |         "test/generated-artifacts/MixinBalancer.json", | ||||||
|         "test/generated-artifacts/MixinBalancerV2.json", |         "test/generated-artifacts/MixinBalancerV2.json", | ||||||
|  |         "test/generated-artifacts/MixinBalancerV2Batch.json", | ||||||
|         "test/generated-artifacts/MixinBancor.json", |         "test/generated-artifacts/MixinBancor.json", | ||||||
|         "test/generated-artifacts/MixinCoFiX.json", |         "test/generated-artifacts/MixinBancorV3.json", | ||||||
|         "test/generated-artifacts/MixinCompound.json", |         "test/generated-artifacts/MixinCompound.json", | ||||||
|         "test/generated-artifacts/MixinCryptoCom.json", |         "test/generated-artifacts/MixinCryptoCom.json", | ||||||
|         "test/generated-artifacts/MixinCurve.json", |         "test/generated-artifacts/MixinCurve.json", | ||||||
|         "test/generated-artifacts/MixinCurveV2.json", |         "test/generated-artifacts/MixinCurveV2.json", | ||||||
|         "test/generated-artifacts/MixinDodo.json", |         "test/generated-artifacts/MixinDodo.json", | ||||||
|         "test/generated-artifacts/MixinDodoV2.json", |         "test/generated-artifacts/MixinDodoV2.json", | ||||||
|         "test/generated-artifacts/MixinKyber.json", |         "test/generated-artifacts/MixinGMX.json", | ||||||
|         "test/generated-artifacts/MixinKyberDmm.json", |         "test/generated-artifacts/MixinKyberDmm.json", | ||||||
|         "test/generated-artifacts/MixinLido.json", |         "test/generated-artifacts/MixinLido.json", | ||||||
|         "test/generated-artifacts/MixinMStable.json", |         "test/generated-artifacts/MixinMStable.json", | ||||||
|         "test/generated-artifacts/MixinMakerPSM.json", |         "test/generated-artifacts/MixinMakerPSM.json", | ||||||
|         "test/generated-artifacts/MixinMooniswap.json", |         "test/generated-artifacts/MixinMooniswap.json", | ||||||
|         "test/generated-artifacts/MixinNerve.json", |         "test/generated-artifacts/MixinNerve.json", | ||||||
|         "test/generated-artifacts/MixinOasis.json", |         "test/generated-artifacts/MixinPlatypus.json", | ||||||
|         "test/generated-artifacts/MixinShell.json", |         "test/generated-artifacts/MixinShell.json", | ||||||
|  |         "test/generated-artifacts/MixinSynthetix.json", | ||||||
|         "test/generated-artifacts/MixinUniswap.json", |         "test/generated-artifacts/MixinUniswap.json", | ||||||
|         "test/generated-artifacts/MixinUniswapV2.json", |         "test/generated-artifacts/MixinUniswapV2.json", | ||||||
|         "test/generated-artifacts/MixinUniswapV3.json", |         "test/generated-artifacts/MixinUniswapV3.json", | ||||||
|  |         "test/generated-artifacts/MixinVelodrome.json", | ||||||
|  |         "test/generated-artifacts/MixinWOOFi.json", | ||||||
|         "test/generated-artifacts/MixinZeroExBridge.json", |         "test/generated-artifacts/MixinZeroExBridge.json", | ||||||
|         "test/generated-artifacts/MooniswapLiquidityProvider.json", |         "test/generated-artifacts/MooniswapLiquidityProvider.json", | ||||||
|         "test/generated-artifacts/MultiplexFeature.json", |         "test/generated-artifacts/MultiplexFeature.json", | ||||||
| @@ -144,16 +176,19 @@ | |||||||
|         "test/generated-artifacts/MultiplexTransformERC20.json", |         "test/generated-artifacts/MultiplexTransformERC20.json", | ||||||
|         "test/generated-artifacts/MultiplexUniswapV2.json", |         "test/generated-artifacts/MultiplexUniswapV2.json", | ||||||
|         "test/generated-artifacts/MultiplexUniswapV3.json", |         "test/generated-artifacts/MultiplexUniswapV3.json", | ||||||
|  |         "test/generated-artifacts/NFTOrders.json", | ||||||
|         "test/generated-artifacts/NativeOrdersCancellation.json", |         "test/generated-artifacts/NativeOrdersCancellation.json", | ||||||
|         "test/generated-artifacts/NativeOrdersFeature.json", |         "test/generated-artifacts/NativeOrdersFeature.json", | ||||||
|         "test/generated-artifacts/NativeOrdersInfo.json", |         "test/generated-artifacts/NativeOrdersInfo.json", | ||||||
|         "test/generated-artifacts/NativeOrdersProtocolFees.json", |         "test/generated-artifacts/NativeOrdersProtocolFees.json", | ||||||
|         "test/generated-artifacts/NativeOrdersSettlement.json", |         "test/generated-artifacts/NativeOrdersSettlement.json", | ||||||
|  |         "test/generated-artifacts/OptimismBridgeAdapter.json", | ||||||
|         "test/generated-artifacts/OtcOrdersFeature.json", |         "test/generated-artifacts/OtcOrdersFeature.json", | ||||||
|         "test/generated-artifacts/OwnableFeature.json", |         "test/generated-artifacts/OwnableFeature.json", | ||||||
|         "test/generated-artifacts/PancakeSwapFeature.json", |         "test/generated-artifacts/PancakeSwapFeature.json", | ||||||
|         "test/generated-artifacts/PayTakerTransformer.json", |         "test/generated-artifacts/PayTakerTransformer.json", | ||||||
|         "test/generated-artifacts/PermissionlessTransformerDeployer.json", |         "test/generated-artifacts/PermissionlessTransformerDeployer.json", | ||||||
|  |         "test/generated-artifacts/PolygonBridgeAdapter.json", | ||||||
|         "test/generated-artifacts/PositiveSlippageFeeTransformer.json", |         "test/generated-artifacts/PositiveSlippageFeeTransformer.json", | ||||||
|         "test/generated-artifacts/SimpleFunctionRegistryFeature.json", |         "test/generated-artifacts/SimpleFunctionRegistryFeature.json", | ||||||
|         "test/generated-artifacts/TestBridge.json", |         "test/generated-artifacts/TestBridge.json", | ||||||
| @@ -161,6 +196,7 @@ | |||||||
|         "test/generated-artifacts/TestCurve.json", |         "test/generated-artifacts/TestCurve.json", | ||||||
|         "test/generated-artifacts/TestDelegateCaller.json", |         "test/generated-artifacts/TestDelegateCaller.json", | ||||||
|         "test/generated-artifacts/TestFeeCollectorController.json", |         "test/generated-artifacts/TestFeeCollectorController.json", | ||||||
|  |         "test/generated-artifacts/TestFeeRecipient.json", | ||||||
|         "test/generated-artifacts/TestFillQuoteTransformerBridge.json", |         "test/generated-artifacts/TestFillQuoteTransformerBridge.json", | ||||||
|         "test/generated-artifacts/TestFillQuoteTransformerExchange.json", |         "test/generated-artifacts/TestFillQuoteTransformerExchange.json", | ||||||
|         "test/generated-artifacts/TestFillQuoteTransformerHost.json", |         "test/generated-artifacts/TestFillQuoteTransformerHost.json", | ||||||
| @@ -175,13 +211,17 @@ | |||||||
|         "test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json", |         "test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json", | ||||||
|         "test/generated-artifacts/TestMigrator.json", |         "test/generated-artifacts/TestMigrator.json", | ||||||
|         "test/generated-artifacts/TestMintTokenERC20Transformer.json", |         "test/generated-artifacts/TestMintTokenERC20Transformer.json", | ||||||
|  |         "test/generated-artifacts/TestMintableERC1155Token.json", | ||||||
|         "test/generated-artifacts/TestMintableERC20Token.json", |         "test/generated-artifacts/TestMintableERC20Token.json", | ||||||
|  |         "test/generated-artifacts/TestMintableERC721Token.json", | ||||||
|         "test/generated-artifacts/TestMooniswap.json", |         "test/generated-artifacts/TestMooniswap.json", | ||||||
|  |         "test/generated-artifacts/TestNFTOrderPresigner.json", | ||||||
|         "test/generated-artifacts/TestNativeOrdersFeature.json", |         "test/generated-artifacts/TestNativeOrdersFeature.json", | ||||||
|         "test/generated-artifacts/TestNoEthRecipient.json", |         "test/generated-artifacts/TestNoEthRecipient.json", | ||||||
|         "test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json", |         "test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json", | ||||||
|         "test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json", |         "test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json", | ||||||
|         "test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json", |         "test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json", | ||||||
|  |         "test/generated-artifacts/TestPropertyValidator.json", | ||||||
|         "test/generated-artifacts/TestRfqOriginRegistration.json", |         "test/generated-artifacts/TestRfqOriginRegistration.json", | ||||||
|         "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json", |         "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json", | ||||||
|         "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json", |         "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json", | ||||||
|   | |||||||
| @@ -4,23 +4,28 @@ Audits | |||||||
|  |  | ||||||
| Below are links to our third-party audit reports. | Below are links to our third-party audit reports. | ||||||
|  |  | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | **Release**      | **Reports**                                                                                                   | | | **Release**          | **Reports**                                                                                                               | | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | Exchange V4      | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__    | | | ERC721OrdersFeature  | * `ABDK Consulting <https://s3.us-east-2.amazonaws.com/zeips.0x.org/audits/abdk-consulting/ABDK_0x_Solidity_v_1_0.pdf>`__ | | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | |                      |                                                                                                                           | | ||||||
| | 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/>`__         | | | ERC1155OrdersFeature |                                                                                                                           | | ||||||
| |                  | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__           | | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | | Exchange V4          | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__                | | ||||||
| | Exchange V2.1    | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_             | | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| |                  | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_                            | | | 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/>`__                     | | ||||||
| | MultiAssetProxy  | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__                              | | |                      | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__                       | | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | ERC1155Proxy     | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__                              | | | Exchange V2.1        | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_                         | | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | |                      | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_                                        | | ||||||
| | StaticCallProxy  | * No third-party audit.                                                                                       | | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | | MultiAssetProxy      | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__                                          | | ||||||
| | ERC20BridgeProxy | * No third-party audit.                                                                                       | | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | | ERC1155Proxy         | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__                                          | | ||||||
|  | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  | | StaticCallProxy      | * No third-party audit.                                                                                                   | | ||||||
|  | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  | | ERC20BridgeProxy     | * No third-party audit.                                                                                                   | | ||||||
|  | +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||||
|   | |||||||
| @@ -2,47 +2,15 @@ | |||||||
| Bounties | 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 bug bounties on this page apply only to the *0x smart contracts* on Ethereum mainnet, Binance Smart Chain, Polygon, Avalanche, Fantom, Celo, Optimism and future deployments in other EVM-compatible networks announced through our official communication channels.   | ||||||
| ------- |  | ||||||
| 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: |  | ||||||
|  |  | ||||||
| +----------------------------+---------------------+ | Bug reports pertaining to 0x API and 0x web interfaces (e.g. Matcha, 0x.org), both in terms of UI/UX or servers/infrastructure, are not eligible. Only the first reporter of a given contract vulnerability will be rewarded, and findings already discovered as part of a formal audit are ineligible.  | ||||||
| | **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.  | Overview | ||||||
|  | -------- | ||||||
|  |  | ||||||
| Areas of Interest | 0x has completed smart contract audits with Consensys Diligence, Trail of Bits and ABDK. We run a continuous bug bounty program for the V4 release of the 0x core contracts. | ||||||
| ----------------- |  | ||||||
|  |  | ||||||
| +---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ |  | ||||||
| | **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 | Scope | ||||||
| ----- | ----- | ||||||
| @@ -51,14 +19,14 @@ The following contracts are in scope of the bug bounty. Please note that any bug | |||||||
| +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | **Release**      | **Contracts**                                                                                                                                                                                                                                                                                 | **Commit Hash**                                                                                                                      | | | **Release**      | **Contracts**                                                                                                                                                                                                                                                                                 | **Commit Hash**                                                                                                                      | | ||||||
| +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | Exchange V4      | * Documentation at `https://0xprotocol.readthedocs.io/en/latest/ <https://0xprotocol.readthedocs.io/en/latest/>`__                                                                                                                                                                            | `72a74e7c66 <https://github.com/0xProject/protocol/tree/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src>`__ | | | Exchange V4      | * Documentation at `https://protocol.0x.org/en/latest/ <https://protocol.0x.org/en/latest/>`__                                                                                                                                                                                                | `2cbeb9c <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src>`__           | | ||||||
| |                  | * `ZeroEx.sol <https://github.com/0xProject/protocol/blob/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/ZeroEx.sol>`__                                                                                                                                             |                                                                                                                                      | | |                  | * `ZeroEx.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/ZeroEx.sol>`__                                                                                                                                                    |                                                                                                                                      | | ||||||
| |                  | * `ZeroExOptimized.sol <https://github.com/0xProject/protocol/blob/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/ZeroExOptimized.sol>`__                                                                                                                           |                                                                                                                                      | | |                  | * `ZeroExOptimized.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/ZeroExOptimized.sol>`__                                                                                                                                  |                                                                                                                                      | | ||||||
| |                  | * `external/*.sol <https://github.com/0xProject/protocol/tree/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/external>`__                                                                                                                                           |                                                                                                                                      | | |                  | * `external/*.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/external>`__                                                                                                                                                  |                                                                                                                                      | | ||||||
| |                  | * `features/**.sol <https://github.com/0xProject/protocol/tree/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/features>`__                                                                                                                                          |                                                                                                                                      | | |                  | * `features/**.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/features>`__                                                                                                                                                 |                                                                                                                                      | | ||||||
| |                  | * `fixins/*.sol <https://github.com/0xProject/protocol/tree/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/fixins>`__                                                                                                                                               |                                                                                                                                      | | |                  | * `fixins/*.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/fixins>`__                                                                                                                                                      |                                                                                                                                      | | ||||||
| |                  | * `migrations/*.sol <https://github.com/0xProject/protocol/tree/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/migrations>`__                                                                                                                                       |                                                                                                                                      | | |                  | * `migrations/*.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/migrations>`__                                                                                                                                              |                                                                                                                                      | | ||||||
| |                  | * `storage/*.sol <https://github.com/0xProject/protocol/tree/72a74e7c66e27da02dd9f4ce604ad057c740c304/contracts/zero-ex/contracts/src/storage>`__                                                                                                                                             |                                                                                                                                      | | |                  | * `storage/*.sol <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src/storage>`__                                                                                                                                                    |                                                                                                                                      | | ||||||
| +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | 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 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>`__)                              |                                                                                                                                      | | |                  | * `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>`__)                              |                                                                                                                                      | | ||||||
| @@ -67,7 +35,7 @@ The following contracts are in scope of the bug bounty. Please note that any bug | |||||||
| |                  | * `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>`__)              |                                                                                                                                      | | |                  | * `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>`__)                      |                                                                                                                                      | | |                  | * `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>`_                     | | | 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/packages/contracts/src/2.0.0>`_  | | ||||||
| |                  | * `src/2.0.0/utils <https://github.com/0xProject/0x-monorepo/tree/ff70c5ecfe28eff14e1a372c5e493b8f5363e1d0/packages/contracts/src/2.0.0/utils>`_                                                                                                                                              |                                                                                                                                      | | |                  | * `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>`_                     | | | 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>`_                     | | ||||||
| @@ -78,9 +46,37 @@ The following contracts are in scope of the bug bounty. Please note that any bug | |||||||
| +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
| | 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>`_                     | | | 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>`_                     | | | ExchangeProxy    | * `contracts/src <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src>`__                                                                                                                                                            | `2cbeb9c <https://github.com/0xProject/protocol/tree/audit/nft-orders-address-findings/contracts/zero-ex/contracts/src>`_            | | ||||||
| +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | +------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  |  | ||||||
|  | Bounties | ||||||
|  | -------- | ||||||
|  | The bounty program will pay out rewards according to the severity of a vulnerability. The severity of reported vulnerabilities will be graded according to the `CVSS <https://www.first.org/cvss/>`__ (Common Vulnerability Scoring Standard). | ||||||
|  |  | ||||||
|  | The final reward amount is at the sole discretion of 0x Labs and will be paid in the specified sum in either USD or ETH.  | ||||||
|  |  | ||||||
|  | +----------------------------+---------------------+ | ||||||
|  | | **Exploit Score**          | **Reward**          | | ||||||
|  | +----------------------------+---------------------+ | ||||||
|  | | Critical (CVSS 9.0 - 10.0) | up to $1,000,000    | | ||||||
|  | +----------------------------+---------------------+ | ||||||
|  | | High (CVSS 7.0 - 8.9)      | up to $350,000      | | ||||||
|  | +----------------------------+---------------------+ | ||||||
|  | | Medium (CVSS 4.0 - 6.9)    | up to $35,000       | | ||||||
|  | +----------------------------+---------------------+ | ||||||
|  | | Low (CVSS 0.0 - 3.9)       | up to $5,000        | | ||||||
|  | +----------------------------+---------------------+ | ||||||
|  |  | ||||||
|  | Recent Inclusions  | ||||||
|  | ----------------- | ||||||
|  |  | ||||||
|  | +---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  | | **Change**                | ****                                                                                                                                                    | | ||||||
|  | +---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  | | NFT feature               | * Trade ERC721 and ERC1155 assets. See `ZEIP-93 <https://github.com/0xProject/ZEIPs/issues/93>`__ for more details                                      | | ||||||
|  | +---------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  |  | ||||||
|  |  | ||||||
| Disclosures | Disclosures | ||||||
| ----------- | ----------- | ||||||
| Please e-mail all submissions to security@0x.org with the subject "BUG BOUNTY". Your submission  | Please e-mail all submissions to security@0x.org with the subject "BUG BOUNTY". Your submission  | ||||||
|   | |||||||
| @@ -17,3 +17,10 @@ Known tokens: | |||||||
| - LINK | - LINK | ||||||
| - sUSD | - sUSD | ||||||
| - USDT | - USDT | ||||||
|  |  | ||||||
|  | Tokens with Fees on Transfer | ||||||
|  | ---------------------------- | ||||||
|  | These tokens do not follow the ERC20 specification. As such the protocol expects the transfer to transfer | ||||||
|  | the specified amount, or revert. Since tokens with transfer fees do not meet this criteria, the behaviour | ||||||
|  | of the protocol with these tokens is unspecified. In most cases it will result in an overall transaction failure | ||||||
|  | due to various slippage protections. | ||||||
| @@ -17,10 +17,12 @@ This page outlines upcoming releases and expected changes. | |||||||
|     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ |     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|     | **Name**                                    | **Overview**                                                  | **Est Release Date** | **Status**  | **Additional**                                                                                                                      | |     | **Name**                                    | **Overview**                                                  | **Est Release Date** | **Status**  | **Additional**                                                                                                                      | | ||||||
|     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ |     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|     | `Amaretto`_                                 | Protocol 4.1: Efficiency + Batch Fills                        | 03/15/21             | Development |                                                                                                                                     | |     | `Nifty`_                                    | ERC721 and ERC1155 support                                    | 02/14/22             | Vote        |                                                                                                                                     | | ||||||
|     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ |     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|     | *The following releases have been deployed* |                                                               |                      |             |                                                                                                                                     | |     | *The following releases have been deployed* |                                                               |                      |             |                                                                                                                                     | | ||||||
|     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ |     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|  |     | `Amaretto`_                                 | Protocol 4.1: Efficiency + Batch Fills                        | 03/15/21             | Deployed    |                                                                                                                                     | | ||||||
|  |     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|     | `Babooshka`_                                | Connect Exchange Proxy to Staking                             | 02/08/21             | Deployed    | `Release Notes <https://github.com/0xProject/0x-migrations/blob/main/src/exchange-proxy/migrations/log/9_babooshka.md>`__           | |     | `Babooshka`_                                | Connect Exchange Proxy to Staking                             | 02/08/21             | Deployed    | `Release Notes <https://github.com/0xProject/0x-migrations/blob/main/src/exchange-proxy/migrations/log/9_babooshka.md>`__           | | ||||||
|     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ |     +---------------------------------------------+---------------------------------------------------------------+----------------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------+ | ||||||
|     | `Squire`_                                   | Aggregation for `V4 Orders <../basics/orders.html>`_          | 02/04/21             | Deployed    | N/A                                                                                                                                 | |     | `Squire`_                                   | Aggregation for `V4 Orders <../basics/orders.html>`_          | 02/04/21             | Deployed    | N/A                                                                                                                                 | | ||||||
| @@ -45,6 +47,19 @@ This page outlines upcoming releases and expected changes. | |||||||
| Upcoming | Upcoming | ||||||
| ======== | ======== | ||||||
|  |  | ||||||
|  | Nifty | ||||||
|  | -------- | ||||||
|  |  | ||||||
|  | - ERC721 and ERC1155 order types | ||||||
|  | - Batch fills for NFT orders | ||||||
|  | - Property based orders | ||||||
|  | - Ability to receive ETH in NFT orders | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Past | ||||||
|  | ===== | ||||||
|  |  | ||||||
| Amaretto | Amaretto | ||||||
| -------- | -------- | ||||||
|  |  | ||||||
| @@ -53,10 +68,6 @@ Amaretto | |||||||
| - Mooniswap VIP | - Mooniswap VIP | ||||||
| - Curve / Swerve VIP (via PLP Sandbox) | - Curve / Swerve VIP (via PLP Sandbox) | ||||||
|  |  | ||||||
|  |  | ||||||
| Past |  | ||||||
| ===== |  | ||||||
|  |  | ||||||
| Babooshka | Babooshka | ||||||
| ---------- | ---------- | ||||||
|  |  | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user