Compare commits
	
		
			32 Commits
		
	
	
		
			protocol@b
			...
			protocol@c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ccf2000c09 | ||
|  | 3eb2e0f56a | ||
|  | d07c7d5b69 | ||
|  | adf6684c29 | ||
|  | 9bf889aa30 | ||
|  | e81c88564e | ||
|  | 901d400d62 | ||
|  | 289474e2ce | ||
|  | 407ca21168 | ||
|  | 5c68fc24d2 | ||
|  | 548800e0a9 | ||
|  | bde3d6dc6a | ||
|  | 56550a6acc | ||
|  | e51b83accc | ||
|  | d5ae971f1c | ||
|  | 5a2f5f9a42 | ||
|  | 75a3b70cef | ||
|  | 803cf65ba1 | ||
|  | 5d3947b838 | ||
|  | 4397a59008 | ||
|  | 966d54c935 | ||
|  | 234ddb495d | ||
|  | a744acc7bc | ||
|  | 27c624633c | ||
|  | 7ef75101b4 | ||
|  | 6f8aace00d | ||
|  | 6c264b2f18 | ||
|  | df055e1958 | ||
|  | 70d2117470 | ||
|  | 2c173ccaf3 | ||
|  | d2f4a0c5f3 | ||
|  | 0d6021e5e3 | 
| @@ -2,11 +2,11 @@ version: 2.1 | ||||
|  | ||||
| jobs: | ||||
|     build: | ||||
|         resource_class: large | ||||
|         resource_class: xlarge | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|         environment: | ||||
|             NODE_OPTIONS: '--max-old-space-size=6442' | ||||
|             NODE_OPTIONS: '--max-old-space-size=16384' | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - checkout | ||||
| @@ -18,8 +18,8 @@ jobs: | ||||
|                   name: yarn | ||||
|                   command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install | ||||
|             - setup_remote_docker | ||||
|             - run: yarn build:ci || yarn build:ci || yarn build:ci | ||||
|             - run: yarn build:ts || yarn build:ts || yarn build:ts | ||||
|             - 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: | ||||
|                   key: repo-{{ .Environment.CIRCLE_SHA1 }} | ||||
|                   paths: | ||||
|   | ||||
| @@ -3,5 +3,6 @@ | ||||
|     "tabWidth": 4, | ||||
|     "singleQuote": true, | ||||
|     "trailingComma": "all", | ||||
|     "bracketSpacing": true | ||||
|     "bracketSpacing": true, | ||||
|     "arrowParens": "avoid" | ||||
| } | ||||
|   | ||||
| @@ -49,7 +49,6 @@ | ||||
| | Package | Version | | ||||
| | ------: | :------ | | ||||
|  | ||||
|  | ||||
| <!-- For example: | ||||
| |             `0x.js` | 2.0.4   | | ||||
| | `Exchange Contract` | v2      | | ||||
|   | ||||
| @@ -43,12 +43,12 @@ These packages are all under development. See [/contracts/README.md](/contracts/ | ||||
| #### 0x-specific packages | ||||
|  | ||||
| | Package                                                  | Version                                                                                                                 | Description                                                                                    | | ||||
| | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | ||||
| | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | ||||
| | [`@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/order-utils`](/packages/order-utils)               | [](https://www.npmjs.com/package/@0x/order-utils)               | A set of utilities for generating, parsing, signing and validating 0x orders                   | | ||||
| | [`@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 | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "3.7.15", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "3.7.14", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "3.7.13", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "3.7.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "3.7.11", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.7.15 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.14 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.13 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.12 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.11 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-asset-proxy", | ||||
|     "version": "3.7.11", | ||||
|     "version": "3.7.15", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,10 +52,10 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contract-wrappers": "^13.16.1", | ||||
|         "@0x/contract-wrappers": "^13.17.1", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
| @@ -80,11 +80,11 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-erc1155": "^2.1.29", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-erc721": "^3.1.29", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/contracts-erc1155": "^2.1.33", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-erc721": "^3.1.33", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.3", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "1.1.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "1.1.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "1.1.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "1.1.30", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "1.1.29", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.1.33 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.32 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.31 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.30 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.29 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-broker", | ||||
|     "version": "1.1.29", | ||||
|     "version": "1.1.33", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,14 +52,14 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-erc721": "^3.1.29", | ||||
|         "@0x/contracts-exchange": "^3.2.30", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-erc721": "^3.1.33", | ||||
|         "@0x/contracts-exchange": "^3.2.34", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
| @@ -85,7 +85,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.3", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|   | ||||
| @@ -7,7 +7,10 @@ export interface GodsUnchainedProperties { | ||||
|     quality: BigNumber | number; | ||||
| } | ||||
|  | ||||
| const propertyDataEncoder = AbiEncoder.create([{ name: 'proto', type: 'uint16' }, { name: 'quality', type: 'uint8' }]); | ||||
| const propertyDataEncoder = AbiEncoder.create([ | ||||
|     { name: 'proto', type: 'uint16' }, | ||||
|     { name: 'quality', type: 'uint8' }, | ||||
| ]); | ||||
| const brokerDataEncoder = AbiEncoder.create([ | ||||
|     { name: 'godsUnchainedAddress', type: 'address' }, | ||||
|     { name: 'validatorAddress', type: 'address' }, | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "3.1.34", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "3.1.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "3.1.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "3.1.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "3.1.30", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.1.34 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.33 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.32 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.31 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.30 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-coordinator", | ||||
|     "version": "3.1.30", | ||||
|     "version": "3.1.34", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,12 +53,12 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-dev-utils": "^1.3.28", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-dev-utils": "^1.3.32", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
| @@ -84,10 +84,10 @@ | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.27", | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contract-addresses": "^6.1.0", | ||||
|         "@0x/contracts-exchange": "^3.2.30", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contract-addresses": "^6.3.1", | ||||
|         "@0x/contracts-exchange": "^3.2.34", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/json-schemas": "^6.1.3", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "1.3.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "1.3.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "1.3.30", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "1.3.29", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "1.3.28", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.3.32 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.31 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.30 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.29 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.28 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-dev-utils", | ||||
|     "version": "1.3.28", | ||||
|     "version": "1.3.32", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -43,10 +43,10 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/assert": "^3.0.27", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "2.1.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "2.1.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "2.1.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "2.1.30", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "2.1.29", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.1.33 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.32 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.31 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.30 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.29 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc1155", | ||||
|     "version": "2.1.29", | ||||
|     "version": "2.1.33", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -54,7 +54,7 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
| @@ -81,7 +81,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/utils": "^6.4.3", | ||||
|         "@0x/web3-wrapper": "^7.5.3", | ||||
|         "lodash": "^4.17.11" | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "3.3.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "3.3.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "3.3.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "3.3.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "3.3.8", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.3.12 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.11 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.10 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.9 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.8 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc20", | ||||
|     "version": "3.3.8", | ||||
|     "version": "3.3.12", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,8 +53,8 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "3.1.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "3.1.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "3.1.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "3.1.30", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "3.1.29", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.1.33 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.32 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.31 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.30 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.29 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc721", | ||||
|     "version": "3.1.29", | ||||
|     "version": "3.1.33", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -54,8 +54,8 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "4.2.34", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "4.2.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "4.2.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "4.2.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "4.2.30", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.2.34 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.2.33 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.2.32 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.2.31 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.2.30 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange-forwarder", | ||||
|     "version": "4.2.30", | ||||
|     "version": "4.2.34", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,18 +53,18 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-dev-utils": "^1.3.28", | ||||
|         "@0x/contracts-erc1155": "^2.1.29", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-erc721": "^3.1.29", | ||||
|         "@0x/contracts-exchange": "^3.2.30", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-dev-utils": "^1.3.32", | ||||
|         "@0x/contracts-erc1155": "^2.1.33", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-erc721": "^3.1.33", | ||||
|         "@0x/contracts-exchange": "^3.2.34", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "4.3.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "4.3.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "4.3.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "4.3.30", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "4.3.29", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.3.33 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.3.32 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.3.31 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.3.30 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.3.29 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange-libs", | ||||
|     "version": "4.3.29", | ||||
|     "version": "4.3.33", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -81,9 +81,9 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.3", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "3.2.34", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "3.2.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "3.2.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "3.2.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "3.2.30", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.2.34 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.33 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.32 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.31 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.30 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange", | ||||
|     "version": "3.2.30", | ||||
|     "version": "3.2.34", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,13 +53,13 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-multisig": "^4.1.30", | ||||
|         "@0x/contracts-staking": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-multisig": "^4.1.34", | ||||
|         "@0x/contracts-staking": "^2.0.41", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
| @@ -89,11 +89,11 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-dev-utils": "^1.3.28", | ||||
|         "@0x/contracts-erc1155": "^2.1.29", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-erc721": "^3.1.29", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/contracts-dev-utils": "^1.3.32", | ||||
|         "@0x/contracts-erc1155": "^2.1.33", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-erc721": "^3.1.33", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/utils": "^6.4.3", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|   | ||||
| @@ -13,7 +13,11 @@ export const exchangeDataEncoder = { | ||||
|                 .getABIEncodedTransactionData(); | ||||
|         } else if (constants.BATCH_FILL_FN_NAMES.indexOf(fnName) !== -1) { | ||||
|             data = (exchangeInstance as any) | ||||
|                 [fnName](orders, orders.map(order => order.takerAssetAmount), orders.map(order => order.signature)) | ||||
|                 [fnName]( | ||||
|                     orders, | ||||
|                     orders.map(order => order.takerAssetAmount), | ||||
|                     orders.map(order => order.signature), | ||||
|                 ) | ||||
|                 .getABIEncodedTransactionData(); | ||||
|         } else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) { | ||||
|             const fillAsset = /Buy/.test(fnName) ? 'makerAssetAmount' : 'takerAssetAmount'; | ||||
|   | ||||
| @@ -39,7 +39,10 @@ blockchainTests.resets('Reentrancy Tests', env => { | ||||
|         // Handle tuples. | ||||
|         if (item.type === 'tuple') { | ||||
|             const tuple = item as TupleDataItem; | ||||
|             return _.zipObject(tuple.components.map(c => c.name), tuple.components.map(createFunctionInputs)); | ||||
|             return _.zipObject( | ||||
|                 tuple.components.map(c => c.name), | ||||
|                 tuple.components.map(createFunctionInputs), | ||||
|             ); | ||||
|         } | ||||
|         // Handle strings. | ||||
|         if (item.type === 'string') { | ||||
|   | ||||
| @@ -109,7 +109,11 @@ export class ExchangeWrapper { | ||||
|         opts: { makerAssetFillAmount: BigNumber; gas?: number; gasPrice?: BigNumber }, | ||||
|     ): Promise<TransactionReceiptWithDecodedLogs> { | ||||
|         return this.exchangeContract | ||||
|             .marketBuyOrdersNoThrow(orders, opts.makerAssetFillAmount, orders.map(signedOrder => signedOrder.signature)) | ||||
|             .marketBuyOrdersNoThrow( | ||||
|                 orders, | ||||
|                 opts.makerAssetFillAmount, | ||||
|                 orders.map(signedOrder => signedOrder.signature), | ||||
|             ) | ||||
|             .awaitTransactionSuccessAsync({ from, gas: opts.gas }); | ||||
|     } | ||||
|     public async marketSellOrdersFillOrKillAsync( | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "6.2.28", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "6.2.27", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "6.2.26", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "6.2.25", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "6.2.24", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v6.2.28 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v6.2.27 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v6.2.26 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v6.2.25 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v6.2.24 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-extensions", | ||||
|     "version": "6.2.24", | ||||
|     "version": "6.2.28", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,16 +53,16 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-dev-utils": "^1.3.28", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-erc721": "^3.1.29", | ||||
|         "@0x/contracts-exchange": "^3.2.30", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-dev-utils": "^1.3.32", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-erc721": "^3.1.33", | ||||
|         "@0x/contracts-exchange": "^3.2.34", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
| @@ -91,7 +91,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-integrations", | ||||
|     "version": "2.7.42", | ||||
|     "version": "2.7.49", | ||||
|     "private": true, | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
| @@ -53,21 +53,21 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contract-addresses": "^6.1.0", | ||||
|         "@0x/contract-wrappers": "^13.16.1", | ||||
|         "@0x/contracts-broker": "^1.1.29", | ||||
|         "@0x/contracts-coordinator": "^3.1.30", | ||||
|         "@0x/contracts-dev-utils": "^1.3.28", | ||||
|         "@0x/contracts-exchange-forwarder": "^4.2.30", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/contracts-extensions": "^6.2.24", | ||||
|         "@0x/contract-addresses": "^6.3.1", | ||||
|         "@0x/contract-wrappers": "^13.17.1", | ||||
|         "@0x/contracts-broker": "^1.1.33", | ||||
|         "@0x/contracts-coordinator": "^3.1.34", | ||||
|         "@0x/contracts-dev-utils": "^1.3.32", | ||||
|         "@0x/contracts-exchange-forwarder": "^4.2.34", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/contracts-extensions": "^6.2.28", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/coordinator-server": "^1.0.5", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/migrations": "^8.0.6", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/protocol-utils": "^1.6.0", | ||||
|         "@0x/migrations": "^8.0.10", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/protocol-utils": "^1.7.1", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/web3-wrapper": "^7.5.3", | ||||
| @@ -93,17 +93,17 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/asset-swapper": "^6.12.0", | ||||
|         "@0x/asset-swapper": "^6.17.2", | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-erc1155": "^2.1.29", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-erc721": "^3.1.29", | ||||
|         "@0x/contracts-exchange": "^3.2.30", | ||||
|         "@0x/contracts-multisig": "^4.1.30", | ||||
|         "@0x/contracts-staking": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-zero-ex": "^0.23.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-erc1155": "^2.1.33", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-erc721": "^3.1.33", | ||||
|         "@0x/contracts-exchange": "^3.2.34", | ||||
|         "@0x/contracts-multisig": "^4.1.34", | ||||
|         "@0x/contracts-staking": "^2.0.41", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-zero-ex": "^0.25.1", | ||||
|         "@0x/subproviders": "^6.5.3", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|   | ||||
| @@ -534,9 +534,14 @@ blockchainTests.skip('Coordinator Client', env => { | ||||
|             const signedOrders = [signedOrder, signedOrderWithDifferentFeeRecipient]; | ||||
|             const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; | ||||
|             await coordinatorClient | ||||
|                 .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), { | ||||
|                     from: takerAddress, | ||||
|                 }) | ||||
|                 .batchFillOrdersAsync( | ||||
|                     signedOrders, | ||||
|                     takerAssetFillAmounts, | ||||
|                     signedOrders.map(o => o.signature), | ||||
|                     { | ||||
|                         from: takerAddress, | ||||
|                     }, | ||||
|                 ) | ||||
|                 .then(res => { | ||||
|                     expect(res).to.be.undefined(); | ||||
|                 }) | ||||
| @@ -570,9 +575,14 @@ blockchainTests.skip('Coordinator Client', env => { | ||||
|             const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; | ||||
|             const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; | ||||
|             await coordinatorClient | ||||
|                 .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), { | ||||
|                     from: takerAddress, | ||||
|                 }) | ||||
|                 .batchFillOrdersAsync( | ||||
|                     signedOrders, | ||||
|                     takerAssetFillAmounts, | ||||
|                     signedOrders.map(o => o.signature), | ||||
|                     { | ||||
|                         from: takerAddress, | ||||
|                     }, | ||||
|                 ) | ||||
|                 .then(res => { | ||||
|                     expect(res).to.be.undefined(); | ||||
|                 }) | ||||
| @@ -600,9 +610,14 @@ blockchainTests.skip('Coordinator Client', env => { | ||||
|             const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator]; | ||||
|             const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount]; | ||||
|             await coordinatorClient | ||||
|                 .batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), { | ||||
|                     from: takerAddress, | ||||
|                 }) | ||||
|                 .batchFillOrdersAsync( | ||||
|                     signedOrders, | ||||
|                     takerAssetFillAmounts, | ||||
|                     signedOrders.map(o => o.signature), | ||||
|                     { | ||||
|                         from: takerAddress, | ||||
|                     }, | ||||
|                 ) | ||||
|                 .then(res => { | ||||
|                     expect(res).to.be.undefined(); | ||||
|                 }) | ||||
|   | ||||
| @@ -267,7 +267,11 @@ blockchainTests.resets('Coordinator integration tests', env => { | ||||
|                 expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value); | ||||
|                 await balanceStore.updateBalancesAsync(); | ||||
|                 balanceStore.assertEquals(expectedBalances); | ||||
|                 verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); | ||||
|                 verifyEvents( | ||||
|                     txReceipt, | ||||
|                     orders.map(order => expectedFillEvent(order)), | ||||
|                     ExchangeEvents.Fill, | ||||
|                 ); | ||||
|             }); | ||||
|             it(`${fnName} should fill the orders if called by approver (eth fee, no refund)`, async () => { | ||||
|                 await balanceStore.updateBalancesAsync(); | ||||
| @@ -280,7 +284,11 @@ blockchainTests.resets('Coordinator integration tests', env => { | ||||
|                 expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value); | ||||
|                 await balanceStore.updateBalancesAsync(); | ||||
|                 balanceStore.assertEquals(expectedBalances); | ||||
|                 verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); | ||||
|                 verifyEvents( | ||||
|                     txReceipt, | ||||
|                     orders.map(order => expectedFillEvent(order)), | ||||
|                     ExchangeEvents.Fill, | ||||
|                 ); | ||||
|             }); | ||||
|             it(`${fnName} should fill the orders if called by approver (mixed fees, refund)`, async () => { | ||||
|                 await balanceStore.updateBalancesAsync(); | ||||
| @@ -293,7 +301,11 @@ blockchainTests.resets('Coordinator integration tests', env => { | ||||
|                 expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value); | ||||
|                 await balanceStore.updateBalancesAsync(); | ||||
|                 balanceStore.assertEquals(expectedBalances); | ||||
|                 verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); | ||||
|                 verifyEvents( | ||||
|                     txReceipt, | ||||
|                     orders.map(order => expectedFillEvent(order)), | ||||
|                     ExchangeEvents.Fill, | ||||
|                 ); | ||||
|             }); | ||||
|             it(`${fnName} should revert with an invalid approval signature`, async () => { | ||||
|                 const approvalSignature = hexUtils.concat( | ||||
| @@ -360,7 +372,11 @@ blockchainTests.resets('Coordinator integration tests', env => { | ||||
|                 .executeTransaction(transaction, maker.address, transaction.signature, []) | ||||
|                 .awaitTransactionSuccessAsync({ from: maker.address }); | ||||
|  | ||||
|             verifyEvents(txReceipt, orders.map(order => expectedCancelEvent(order)), ExchangeEvents.Cancel); | ||||
|             verifyEvents( | ||||
|                 txReceipt, | ||||
|                 orders.map(order => expectedCancelEvent(order)), | ||||
|                 ExchangeEvents.Cancel, | ||||
|             ); | ||||
|         }); | ||||
|         it('cancelOrdersUpTo call should be successful without an approval', async () => { | ||||
|             const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo, []); | ||||
|   | ||||
| @@ -186,13 +186,13 @@ blockchainTests.resets('LibAssetData', env => { | ||||
|         }); | ||||
|  | ||||
|         it('should decode multiasset data', async () => { | ||||
|             expect(await devUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData).callAsync()).to.deep.equal( | ||||
|                 [ | ||||
|                     AssetProxyId.MultiAsset, | ||||
|                     KNOWN_MULTI_ASSET_ENCODING.amounts, | ||||
|                     KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, | ||||
|                 ], | ||||
|             ); | ||||
|             expect( | ||||
|                 await devUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData).callAsync(), | ||||
|             ).to.deep.equal([ | ||||
|                 AssetProxyId.MultiAsset, | ||||
|                 KNOWN_MULTI_ASSET_ENCODING.amounts, | ||||
|                 KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, | ||||
|             ]); | ||||
|         }); | ||||
|  | ||||
|         it('should encode StaticCall data', async () => { | ||||
|   | ||||
| @@ -278,15 +278,21 @@ blockchainTests.resets('matchOrders integration tests', env => { | ||||
|                 ExchangeRevertErrors.BatchMatchOrdersErrorCodes.InvalidLengthRightSignatures, | ||||
|             ); | ||||
|             let tx = deployment.exchange | ||||
|                 .batchMatchOrders(leftOrders, rightOrders, leftOrders.map(order => order.signature), [ | ||||
|                     rightOrders[0].signature, | ||||
|                 ]) | ||||
|                 .batchMatchOrders( | ||||
|                     leftOrders, | ||||
|                     rightOrders, | ||||
|                     leftOrders.map(order => order.signature), | ||||
|                     [rightOrders[0].signature], | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: matcher.address }); | ||||
|             await expect(tx).to.revertWith(expectedError); | ||||
|             tx = deployment.exchange | ||||
|                 .batchMatchOrdersWithMaximalFill(leftOrders, rightOrders, leftOrders.map(order => order.signature), [ | ||||
|                     rightOrders[0].signature, | ||||
|                 ]) | ||||
|                 .batchMatchOrdersWithMaximalFill( | ||||
|                     leftOrders, | ||||
|                     rightOrders, | ||||
|                     leftOrders.map(order => order.signature), | ||||
|                     [rightOrders[0].signature], | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: matcher.address }); | ||||
|             return expect(tx).to.revertWith(expectedError); | ||||
|         }); | ||||
| @@ -475,7 +481,10 @@ blockchainTests.resets('matchOrders integration tests', env => { | ||||
|                 ], | ||||
|                 leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT], | ||||
|                 rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT], | ||||
|                 matchIndices: [[0, 0], [1, 0]], | ||||
|                 matchIndices: [ | ||||
|                     [0, 0], | ||||
|                     [1, 0], | ||||
|                 ], | ||||
|                 shouldMaximallyFill: false, | ||||
|             }); | ||||
|         }); | ||||
| @@ -524,7 +533,10 @@ blockchainTests.resets('matchOrders integration tests', env => { | ||||
|                 ], | ||||
|                 leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT], | ||||
|                 rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT], | ||||
|                 matchIndices: [[0, 0], [0, 1]], | ||||
|                 matchIndices: [ | ||||
|                     [0, 0], | ||||
|                     [0, 1], | ||||
|                 ], | ||||
|                 shouldMaximallyFill: false, | ||||
|             }); | ||||
|         }); | ||||
| @@ -626,7 +638,11 @@ blockchainTests.resets('matchOrders integration tests', env => { | ||||
|                 ], | ||||
|                 leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT], | ||||
|                 rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT], | ||||
|                 matchIndices: [[0, 0], [0, 1], [1, 1]], | ||||
|                 matchIndices: [ | ||||
|                     [0, 0], | ||||
|                     [0, 1], | ||||
|                     [1, 1], | ||||
|                 ], | ||||
|                 shouldMaximallyFill: false, | ||||
|             }); | ||||
|         }); | ||||
| @@ -801,7 +817,11 @@ blockchainTests.resets('matchOrders integration tests', env => { | ||||
|                 ], | ||||
|                 leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT], | ||||
|                 rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT], | ||||
|                 matchIndices: [[0, 0], [1, 0], [1, 1]], | ||||
|                 matchIndices: [ | ||||
|                     [0, 0], | ||||
|                     [1, 0], | ||||
|                     [1, 1], | ||||
|                 ], | ||||
|                 shouldMaximallyFill: true, | ||||
|             }); | ||||
|         }); | ||||
|   | ||||
| @@ -106,7 +106,12 @@ blockchainTests.fork.resets('Forwarder mainnet tests', env => { | ||||
|                 orders[1].takerAssetAmount.dividedToIntegerBy(2), | ||||
|             ); | ||||
|             const [wethSpentAmount, makerAssetAcquiredAmount] = await forwarder | ||||
|                 .marketSellOrdersWithEth(orders, orders.map(o => o.signature), [], []) | ||||
|                 .marketSellOrdersWithEth( | ||||
|                     orders, | ||||
|                     orders.map(o => o.signature), | ||||
|                     [], | ||||
|                     [], | ||||
|                 ) | ||||
|                 .callAsync({ | ||||
|                     from: takerAddress, | ||||
|                     value: ethSellAmount, | ||||
| @@ -161,7 +166,13 @@ blockchainTests.fork.resets('Forwarder mainnet tests', env => { | ||||
|                 orders[1].makerAssetAmount.dividedToIntegerBy(2), | ||||
|             ); | ||||
|             const [wethSpentAmount, makerAssetAcquiredAmount] = await forwarder | ||||
|                 .marketBuyOrdersWithEth(orders, makerAssetBuyAmount, orders.map(o => o.signature), [], []) | ||||
|                 .marketBuyOrdersWithEth( | ||||
|                     orders, | ||||
|                     makerAssetBuyAmount, | ||||
|                     orders.map(o => o.signature), | ||||
|                     [], | ||||
|                     [], | ||||
|                 ) | ||||
|                 .callAsync({ | ||||
|                     from: takerAddress, | ||||
|                     value: ethSellAmount, | ||||
|   | ||||
| @@ -190,9 +190,14 @@ export function MakerMixin<TBase extends Constructor>(Base: TBase): TBase & Cons | ||||
|                 rightTakerAssetData, | ||||
|                 makerFeeAssetData, | ||||
|                 takerFeeAssetData, | ||||
|             ] = [leftMakerToken, leftTakerToken, rightMakerToken, rightTakerToken, makerFeeToken, takerFeeToken].map( | ||||
|                 token => encodeERC20AssetData(token.address), | ||||
|             ); | ||||
|             ] = [ | ||||
|                 leftMakerToken, | ||||
|                 leftTakerToken, | ||||
|                 rightMakerToken, | ||||
|                 rightTakerToken, | ||||
|                 makerFeeToken, | ||||
|                 takerFeeToken, | ||||
|             ].map(token => encodeERC20AssetData(token.address)); | ||||
|  | ||||
|             // Construct and sign the left order | ||||
|             const leftOrder = await this.signOrderAsync({ | ||||
|   | ||||
| @@ -8,7 +8,10 @@ import { Actor, Constructor } from './base'; | ||||
|  * Useful for BalanceStore. | ||||
|  */ | ||||
| export function actorAddressesByName(actors: Actor[]): ObjectMap<string> { | ||||
|     return _.zipObject(actors.map(actor => actor.name), actors.map(actor => actor.address)); | ||||
|     return _.zipObject( | ||||
|         actors.map(actor => actor.name), | ||||
|         actors.map(actor => actor.address), | ||||
|     ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -77,19 +77,24 @@ tests('Exchange signature validation fuzz tests', env => { | ||||
|     before(async () => { | ||||
|         chainId = await env.web3Wrapper.getChainIdAsync(); | ||||
|         accounts = await env.getAccountAddressesAsync(); | ||||
|         privateKeys = _.zipObject(accounts, accounts.map((a, i) => constants.TESTRPC_PRIVATE_KEYS[i])); | ||||
|         privateKeys = _.zipObject( | ||||
|             accounts, | ||||
|             accounts.map((a, i) => constants.TESTRPC_PRIVATE_KEYS[i]), | ||||
|         ); | ||||
|         deployment = await DeploymentManager.deployAsync(env, { | ||||
|             numErc20TokensToDeploy: 0, | ||||
|             numErc721TokensToDeploy: 0, | ||||
|             numErc1155TokensToDeploy: 0, | ||||
|         }); | ||||
|         exchange = deployment.exchange; | ||||
|         walletContractAddress = (await TestSignatureValidationWalletContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestSignatureValidationWallet, | ||||
|             env.provider, | ||||
|             env.txDefaults, | ||||
|             {}, | ||||
|         )).address; | ||||
|         walletContractAddress = ( | ||||
|             await TestSignatureValidationWalletContract.deployFrom0xArtifactAsync( | ||||
|                 artifacts.TestSignatureValidationWallet, | ||||
|                 env.provider, | ||||
|                 env.txDefaults, | ||||
|                 {}, | ||||
|             ) | ||||
|         ).address; | ||||
|         // This just has to be a contract address that doesn't implement the | ||||
|         // wallet spec. | ||||
|         notWalletContractAddress = exchange.address; | ||||
| @@ -715,7 +720,7 @@ tests('Exchange signature validation fuzz tests', env => { | ||||
|             invalidTestTransactionMangledSignature(), | ||||
|         ]; | ||||
|         const simulationEnvironment = new SimulationEnvironment(deployment, new BlockchainBalanceStore({}, {}), []); | ||||
|         const simulation = new class extends Simulation { | ||||
|         const simulation = new (class extends Simulation { | ||||
|             // tslint:disable-next-line: prefer-function-over-method | ||||
|             protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> { | ||||
|                 while (true) { | ||||
| @@ -723,7 +728,7 @@ tests('Exchange signature validation fuzz tests', env => { | ||||
|                     yield (await action!.next()).value; | ||||
|                 } | ||||
|             } | ||||
|         }(simulationEnvironment); | ||||
|         })(simulationEnvironment); | ||||
|         simulation.resets = true; | ||||
|         return simulation.fuzzAsync(); | ||||
|     }); | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "4.1.34", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "4.1.33", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "4.1.32", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "4.1.31", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "4.1.30", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.1.34 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.1.33 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.1.32 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.1.31 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.1.30 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-multisig", | ||||
|     "version": "4.1.30", | ||||
|     "version": "4.1.34", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -50,11 +50,11 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "2.0.41", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "2.0.40", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "2.0.39", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "2.0.38", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "2.0.37", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.0.41 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.40 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.39 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.38 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.37 - _May 5, 2021_ | ||||
|  | ||||
|     * Patch epoch finalization issue (#221) | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-staking", | ||||
|     "version": "2.0.37", | ||||
|     "version": "2.0.41", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -54,14 +54,14 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-dev-utils": "^1.3.28", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.29", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-dev-utils": "^1.3.32", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.33", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-utils": "^4.7.8", | ||||
|         "@0x/contracts-utils": "^4.7.12", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
| @@ -88,7 +88,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.3", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|   | ||||
| @@ -157,11 +157,11 @@ export class FinalizerActor extends BaseActor { | ||||
|             const delegators = delegatorsByPoolId[poolId]; | ||||
|             delegatorBalancesByPoolId[poolId] = {}; | ||||
|             for (const delegator of delegators) { | ||||
|                 delegatorBalancesByPoolId[poolId][ | ||||
|                     delegator | ||||
|                 ] = (await this._stakingApiWrapper.stakingContract | ||||
|                     .getStakeDelegatedToPoolByOwner(delegator, poolId) | ||||
|                     .callAsync()).currentEpochBalance; | ||||
|                 delegatorBalancesByPoolId[poolId][delegator] = ( | ||||
|                     await this._stakingApiWrapper.stakingContract | ||||
|                         .getStakeDelegatedToPoolByOwner(delegator, poolId) | ||||
|                         .callAsync() | ||||
|                 ).currentEpochBalance; | ||||
|             } | ||||
|         } | ||||
|         return delegatorBalancesByPoolId; | ||||
| @@ -253,7 +253,10 @@ export class FinalizerActor extends BaseActor { | ||||
|         const totalFeesCollected = BigNumber.sum(...activePools.map(p => p.feesCollected)); | ||||
|         const totalWeightedStake = BigNumber.sum(...activePools.map(p => p.weightedStake)); | ||||
|         if (totalRewards.eq(0) || totalFeesCollected.eq(0) || totalWeightedStake.eq(0)) { | ||||
|             return _.zipObject(poolIds, _.times(poolIds.length, () => new BigNumber(0))); | ||||
|             return _.zipObject( | ||||
|                 poolIds, | ||||
|                 _.times(poolIds.length, () => new BigNumber(0)), | ||||
|             ); | ||||
|         } | ||||
|         const rewards = await Promise.all( | ||||
|             activePools.map(async pool => | ||||
|   | ||||
| @@ -102,13 +102,15 @@ blockchainTests('Migration tests', env => { | ||||
|             }); | ||||
|  | ||||
|             it('should set the correct initial params', async () => { | ||||
|                 const stakingProxyContractAddress = (await StakingProxyContract.deployFrom0xArtifactAsync( | ||||
|                     artifacts.StakingProxy, | ||||
|                     env.provider, | ||||
|                     env.txDefaults, | ||||
|                     artifacts, | ||||
|                     stakingContract.address, | ||||
|                 )).address; | ||||
|                 const stakingProxyContractAddress = ( | ||||
|                     await StakingProxyContract.deployFrom0xArtifactAsync( | ||||
|                         artifacts.StakingProxy, | ||||
|                         env.provider, | ||||
|                         env.txDefaults, | ||||
|                         artifacts, | ||||
|                         stakingContract.address, | ||||
|                     ) | ||||
|                 ).address; | ||||
|  | ||||
|                 const stakingProxyContract = new StakingContract( | ||||
|                     stakingProxyContractAddress, | ||||
|   | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "5.4.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "5.4.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "5.4.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "5.4.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "5.4.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v5.4.4 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v5.4.3 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v5.4.2 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v5.4.1 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v5.4.0 - _May 5, 2021_ | ||||
|  | ||||
|     * Set default ganache gas limit to 100e6 (#197) | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-test-utils", | ||||
|     "version": "5.4.0", | ||||
|     "version": "5.4.4", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -44,10 +44,10 @@ | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.27", | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contract-addresses": "^6.1.0", | ||||
|         "@0x/contract-addresses": "^6.3.1", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/json-schemas": "^6.1.3", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/sol-coverage": "^4.0.37", | ||||
|         "@0x/sol-profiler": "^4.1.27", | ||||
|         "@0x/sol-trace": "^3.0.37", | ||||
|   | ||||
| @@ -108,9 +108,7 @@ export async function testWithReferenceFuncAsync( | ||||
|                     return expect.fail( | ||||
|                         actualError, | ||||
|                         expectedError, | ||||
|                         `${testCaseString}: expected error message '${actualError.message}' to equal '${ | ||||
|                             expectedError.message | ||||
|                         }'`, | ||||
|                         `${testCaseString}: expected error message '${actualError.message}' to equal '${expectedError.message}'`, | ||||
|                     ); | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -1,4 +1,50 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "1.2.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "1.2.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.2.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Added proposal 0 params and test", | ||||
|                 "pr": 252 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1622154125 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "1.1.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "1.1.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "1.1.6", | ||||
|   | ||||
| @@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.2.2 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.2.1 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.2.0 - _May 27, 2021_ | ||||
|  | ||||
|     * Added proposal 0 params and test (#252) | ||||
|  | ||||
| ## v1.1.8 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.7 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.6 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-treasury", | ||||
|     "version": "1.1.6", | ||||
|     "version": "1.2.2", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,12 +47,12 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contract-addresses": "^6.1.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.11", | ||||
|         "@0x/contracts-erc20": "^3.3.8", | ||||
|         "@0x/contract-addresses": "^6.3.1", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.15", | ||||
|         "@0x/contracts-erc20": "^3.3.12", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-staking": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-staking": "^2.0.41", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
| @@ -73,7 +73,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/protocol-utils": "^1.6.0", | ||||
|         "@0x/protocol-utils": "^1.7.1", | ||||
|         "@0x/subproviders": "^6.5.3", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|   | ||||
							
								
								
									
										35
									
								
								contracts/treasury/src/proposals.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								contracts/treasury/src/proposals.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										154
									
								
								contracts/treasury/test/proposal_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								contracts/treasury/test/proposal_test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| import { artifacts as erc20Artifacts, ERC20TokenEvents } from '@0x/contracts-erc20'; | ||||
| import { StakingContract, StakingProxyContract } from '@0x/contracts-staking'; | ||||
| import { blockchainTests, constants, verifyEventsFromLogs } from '@0x/contracts-test-utils'; | ||||
| import { BigNumber, hexUtils, logUtils } from '@0x/utils'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { proposals } from '../src/proposals'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
| import { ZrxTreasuryContract, ZrxTreasuryEvents } from './wrappers'; | ||||
|  | ||||
| const SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/mzhu25/zeroex-staking'; | ||||
| const STAKING_PROXY_ADDRESS = '0xa26e80e7dea86279c6d778d702cc413e6cffa777'; | ||||
| const TREASURY_ADDRESS = '0x0bb1810061c2f5b2088054ee184e6c79e1591101'; | ||||
| const PROPOSER = process.env.PROPOSER || constants.NULL_ADDRESS; | ||||
| const VOTER = '0xba4f44e774158408e2dc6c5cb65bc995f0a89180'; | ||||
| const VOTER_OPERATED_POOLS = ['0x0000000000000000000000000000000000000000000000000000000000000017']; | ||||
| blockchainTests.configure({ | ||||
|     fork: { | ||||
|         unlockedAccounts: [PROPOSER, VOTER], | ||||
|     }, | ||||
| }); | ||||
|  | ||||
| async function querySubgraphAsync(operatorAddress: string): Promise<string[]> { | ||||
|     const query = ` | ||||
|         { | ||||
|             stakingActor(id: "${operatorAddress}") { | ||||
|                 operatedPools { | ||||
|                     id | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     `; | ||||
|     const response = await fetch(SUBGRAPH_URL, { | ||||
|         method: 'POST', | ||||
|         headers: { | ||||
|             Accept: 'application/json', | ||||
|             'Content-Type': 'application/json', | ||||
|         }, | ||||
|         body: JSON.stringify({ | ||||
|             query, | ||||
|         }), | ||||
|     }); | ||||
|     const { | ||||
|         data: { stakingActor }, | ||||
|     } = await response.json(); | ||||
|     if (stakingActor) { | ||||
|         return stakingActor.operatedPools.map((pool: { id: string }) => hexUtils.leftPad(pool.id)); | ||||
|     } else { | ||||
|         return []; | ||||
|     } | ||||
| } | ||||
|  | ||||
| blockchainTests.fork.skip('Treasury proposal mainnet fork tests', env => { | ||||
|     let staking: StakingContract; | ||||
|     let stakingProxy: StakingProxyContract; | ||||
|     let treasury: ZrxTreasuryContract; | ||||
|     let votingPeriod: BigNumber; | ||||
|  | ||||
|     async function fastForwardToNextEpochAsync(): Promise<void> { | ||||
|         const epochEndTime = await staking.getCurrentEpochEarliestEndTimeInSeconds().callAsync(); | ||||
|         const lastBlockTime = await env.web3Wrapper.getBlockTimestampAsync('latest'); | ||||
|         const dt = Math.max(0, epochEndTime.minus(lastBlockTime).toNumber()); | ||||
|         await env.web3Wrapper.increaseTimeAsync(dt); | ||||
|         // mine next block | ||||
|         await env.web3Wrapper.mineBlockAsync(); | ||||
|         const lastPoolId = new BigNumber(await staking.lastPoolId().callAsync(), 16); | ||||
|         const batchExecuteCalldata = [ | ||||
|             ...[...new Array(lastPoolId.toNumber())].map((_x, i) => | ||||
|                 staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(), | ||||
|             ), | ||||
|             staking.endEpoch().getABIEncodedTransactionData(), | ||||
|             ...[...new Array(lastPoolId.toNumber())].map((_x, i) => | ||||
|                 staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(), | ||||
|             ), | ||||
|             ...[...new Array(lastPoolId.toNumber())].map((_x, i) => | ||||
|                 staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(), | ||||
|             ), | ||||
|         ]; | ||||
|         await stakingProxy.batchExecute(batchExecuteCalldata).awaitTransactionSuccessAsync(); | ||||
|     } | ||||
|  | ||||
|     before(async () => { | ||||
|         const abis = _.mapValues({ ...artifacts, ...erc20Artifacts }, v => v.compilerOutput.abi); | ||||
|         treasury = new ZrxTreasuryContract(TREASURY_ADDRESS, env.provider, env.txDefaults, abis); | ||||
|         votingPeriod = await treasury.votingPeriod().callAsync(); | ||||
|         staking = new StakingContract(STAKING_PROXY_ADDRESS, env.provider, env.txDefaults); | ||||
|         stakingProxy = new StakingProxyContract(STAKING_PROXY_ADDRESS, env.provider, env.txDefaults); | ||||
|     }); | ||||
|  | ||||
|     describe('Proposal 0', () => { | ||||
|         it('works', async () => { | ||||
|             const proposal = proposals[0]; | ||||
|             let executionEpoch: BigNumber; | ||||
|             if (proposal.executionEpoch) { | ||||
|                 executionEpoch = proposal.executionEpoch; | ||||
|             } else { | ||||
|                 const currentEpoch = await staking.currentEpoch().callAsync(); | ||||
|                 executionEpoch = currentEpoch.plus(2); | ||||
|             } | ||||
|             const pools = await querySubgraphAsync(PROPOSER); | ||||
|             const proposeTx = treasury.propose(proposal.actions, executionEpoch, proposal.description, pools); | ||||
|  | ||||
|             const calldata = proposeTx.getABIEncodedTransactionData(); | ||||
|             logUtils.log('ZrxTreasury.propose calldata:'); | ||||
|             logUtils.log(calldata); | ||||
|  | ||||
|             const proposalId = await proposeTx.callAsync({ from: PROPOSER }); | ||||
|             const receipt = await proposeTx.awaitTransactionSuccessAsync({ from: PROPOSER }); | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         ...proposal, | ||||
|                         proposalId, | ||||
|                         executionEpoch, | ||||
|                         proposer: PROPOSER, | ||||
|                         operatedPoolIds: pools, | ||||
|                     }, | ||||
|                 ], | ||||
|                 ZrxTreasuryEvents.ProposalCreated, | ||||
|             ); | ||||
|             await fastForwardToNextEpochAsync(); | ||||
|             await fastForwardToNextEpochAsync(); | ||||
|             await treasury | ||||
|                 .castVote(proposalId, true, VOTER_OPERATED_POOLS) | ||||
|                 .awaitTransactionSuccessAsync({ from: VOTER }); | ||||
|             await env.web3Wrapper.increaseTimeAsync(votingPeriod.plus(1).toNumber()); | ||||
|             await env.web3Wrapper.mineBlockAsync(); | ||||
|             const executeTx = await treasury.execute(proposalId, proposal.actions).awaitTransactionSuccessAsync(); | ||||
|             verifyEventsFromLogs( | ||||
|                 executeTx.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         proposalId, | ||||
|                     }, | ||||
|                 ], | ||||
|                 ZrxTreasuryEvents.ProposalExecuted, | ||||
|             ); | ||||
|             const recipient = '0xf9347f751a6a1467abc722ec7d80ba2698dd9d6c'; | ||||
|             verifyEventsFromLogs( | ||||
|                 executeTx.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         _from: TREASURY_ADDRESS, | ||||
|                         _to: recipient, | ||||
|                         _value: new BigNumber(400_000).times('1e18'), | ||||
|                     }, | ||||
|                 ], | ||||
|                 ERC20TokenEvents.Transfer, | ||||
|             ); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -1,4 +1,40 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "4.7.12", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1622609597, | ||||
|         "version": "4.7.11", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "4.7.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621600614, | ||||
|         "version": "4.7.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1620214333, | ||||
|         "version": "4.7.8", | ||||
|   | ||||
| @@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.7.12 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.7.11 - _June 2, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.7.10 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.7.9 - _May 21, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.7.8 - _May 5, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-utils", | ||||
|     "version": "4.7.8", | ||||
|     "version": "4.7.12", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,9 +52,9 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-gen": "^2.0.38", | ||||
|         "@0x/contracts-test-utils": "^5.4.0", | ||||
|         "@0x/contracts-test-utils": "^5.4.4", | ||||
|         "@0x/dev-utils": "^4.2.7", | ||||
|         "@0x/order-utils": "^10.4.21", | ||||
|         "@0x/order-utils": "^10.4.25", | ||||
|         "@0x/sol-compiler": "^4.7.3", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|   | ||||
| @@ -536,7 +536,11 @@ blockchainTests('LibBytes', env => { | ||||
|             ])); | ||||
|  | ||||
|         describe('copies forward within one word and one byte overlap', () => | ||||
|             test([[0, 0, 1, 'one byte'], [10, 0, 11, 'eleven bytes'], [15, 0, 16, 'sixteen bytes']])); | ||||
|             test([ | ||||
|                 [0, 0, 1, 'one byte'], | ||||
|                 [10, 0, 11, 'eleven bytes'], | ||||
|                 [15, 0, 16, 'sixteen bytes'], | ||||
|             ])); | ||||
|  | ||||
|         describe('copies backward', () => | ||||
|             test([ | ||||
| @@ -603,7 +607,11 @@ blockchainTests('LibBytes', env => { | ||||
|             ])); | ||||
|  | ||||
|         describe('copies forward within one word and one byte overlap', () => | ||||
|             test([[0, 0, 1, 'one byte'], [0, 10, 11, 'eleven bytes'], [0, 15, 16, 'sixteen bytes']])); | ||||
|             test([ | ||||
|                 [0, 0, 1, 'one byte'], | ||||
|                 [0, 10, 11, 'eleven bytes'], | ||||
|                 [0, 15, 16, 'sixteen bytes'], | ||||
|             ])); | ||||
|     }); | ||||
|  | ||||
|     describe('slice', () => { | ||||
|   | ||||
| @@ -1,4 +1,46 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1623382456, | ||||
|         "version": "0.25.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.25.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add OtcOrdersFeature", | ||||
|                 "pr": 244 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add UniswapV3 VIP feature", | ||||
|                 "pr": 237 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1622609597 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1621944788, | ||||
|         "version": "0.24.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.24.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add special selectors to selector collision test", | ||||
|                 "pr": 243 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1621600614 | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.23.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,23 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v0.25.1 - _June 11, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.25.0 - _June 2, 2021_ | ||||
|  | ||||
|     * Add OtcOrdersFeature (#244) | ||||
|     * Add UniswapV3 VIP feature (#237) | ||||
|  | ||||
| ## v0.24.1 - _May 25, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.24.0 - _May 21, 2021_ | ||||
|  | ||||
|     * Add special selectors to selector collision test (#243) | ||||
|  | ||||
| ## v0.23.0 - _May 5, 2021_ | ||||
|  | ||||
|     * Added ETH support to `MixinCurve` (#220) | ||||
|   | ||||
| @@ -26,11 +26,13 @@ import "./features/interfaces/ITokenSpenderFeature.sol"; | ||||
| import "./features/interfaces/ITransformERC20Feature.sol"; | ||||
| import "./features/interfaces/IMetaTransactionsFeature.sol"; | ||||
| import "./features/interfaces/IUniswapFeature.sol"; | ||||
| import "./features/interfaces/IUniswapV3Feature.sol"; | ||||
| import "./features/interfaces/IPancakeSwapFeature.sol"; | ||||
| import "./features/interfaces/ILiquidityProviderFeature.sol"; | ||||
| import "./features/interfaces/INativeOrdersFeature.sol"; | ||||
| import "./features/interfaces/IBatchFillNativeOrdersFeature.sol"; | ||||
| import "./features/interfaces/IMultiplexFeature.sol"; | ||||
| import "./features/interfaces/IOtcOrdersFeature.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev Interface for a fully featured Exchange Proxy. | ||||
| @@ -40,11 +42,13 @@ interface IZeroEx is | ||||
|     ITransformERC20Feature, | ||||
|     IMetaTransactionsFeature, | ||||
|     IUniswapFeature, | ||||
|     IUniswapV3Feature, | ||||
|     IPancakeSwapFeature, | ||||
|     ILiquidityProviderFeature, | ||||
|     INativeOrdersFeature, | ||||
|     IBatchFillNativeOrdersFeature, | ||||
|     IMultiplexFeature | ||||
|     IMultiplexFeature, | ||||
|     IOtcOrdersFeature | ||||
| { | ||||
|     // solhint-disable state-visibility | ||||
|  | ||||
|   | ||||
| @@ -88,6 +88,23 @@ library LibNativeOrdersRichErrors { | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function OrderNotSignedByTakerError( | ||||
|         bytes32 orderHash, | ||||
|         address signer, | ||||
|         address taker | ||||
|     ) | ||||
|         internal | ||||
|         pure | ||||
|         returns (bytes memory) | ||||
|     { | ||||
|         return abi.encodeWithSelector( | ||||
|             bytes4(keccak256("OrderNotSignedByTakerError(bytes32,address,address)")), | ||||
|             orderHash, | ||||
|             signer, | ||||
|             taker | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function InvalidSignerError( | ||||
|         address maker, | ||||
|         address signer | ||||
|   | ||||
| @@ -108,7 +108,7 @@ contract LiquidityProviderFeature is | ||||
|  | ||||
|         if (!LibERC20Transformer.isTokenETH(inputToken)) { | ||||
|             // Transfer input ERC20 tokens to the provider. | ||||
|             _transferERC20Tokens( | ||||
|             _transferERC20TokensFrom( | ||||
|                 inputToken, | ||||
|                 msg.sender, | ||||
|                 address(provider), | ||||
|   | ||||
| @@ -251,7 +251,7 @@ contract MetaTransactionsFeature is | ||||
|  | ||||
|         // Pay the fee to the sender. | ||||
|         if (state.mtx.feeAmount > 0) { | ||||
|             _transferERC20Tokens( | ||||
|             _transferERC20TokensFrom( | ||||
|                 state.mtx.feeToken, | ||||
|                 state.mtx.signer, | ||||
|                 state.sender, | ||||
|   | ||||
| @@ -36,6 +36,7 @@ import "./interfaces/IFeature.sol"; | ||||
| import "./interfaces/IMultiplexFeature.sol"; | ||||
| import "./interfaces/INativeOrdersFeature.sol"; | ||||
| import "./interfaces/ITransformERC20Feature.sol"; | ||||
| import "./interfaces/IUniswapV3Feature.sol"; | ||||
| import "./libs/LibNativeOrder.sol"; | ||||
|  | ||||
|  | ||||
| @@ -55,7 +56,7 @@ contract MultiplexFeature is | ||||
|     /// @dev Name of this feature. | ||||
|     string public constant override FEATURE_NAME = "MultiplexFeature"; | ||||
|     /// @dev Version of this feature. | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 1); | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0); | ||||
|  | ||||
|     /// @dev The WETH token contract. | ||||
|     IEtherTokenV06 private immutable weth; | ||||
| @@ -273,6 +274,22 @@ contract MultiplexFeature is | ||||
|                 // Increment the sold and bought amounts. | ||||
|                 soldAmount = soldAmount.safeAdd(inputTokenAmount); | ||||
|                 outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_); | ||||
|             } else if (wrappedCall.selector == IUniswapV3Feature.sellTokenForTokenToUniswapV3.selector) { | ||||
|                 (bool success, bytes memory resultData) = address(this).delegatecall( | ||||
|                     abi.encodeWithSelector( | ||||
|                         IUniswapV3Feature.sellTokenForTokenToUniswapV3.selector, | ||||
|                         wrappedCall.data, | ||||
|                         inputTokenAmount, | ||||
|                         0, | ||||
|                         msg.sender | ||||
|                     ) | ||||
|                 ); | ||||
|                 if (success) { | ||||
|                     uint256 outputTokenAmount_ = abi.decode(resultData, (uint256)); | ||||
|                     // Increment the sold and bought amounts. | ||||
|                     soldAmount = soldAmount.safeAdd(inputTokenAmount); | ||||
|                     outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_); | ||||
|                 } | ||||
|             } else if (wrappedCall.selector == this._sellToLiquidityProvider.selector) { | ||||
|                 (address provider, bytes memory auxiliaryData) = abi.decode( | ||||
|                     wrappedCall.data, | ||||
| @@ -289,7 +306,7 @@ contract MultiplexFeature is | ||||
|                     remainingEth -= inputTokenAmount; | ||||
|                 } else { | ||||
|                     // Transfer input ERC20 tokens to the provider. | ||||
|                     _transferERC20Tokens( | ||||
|                     _transferERC20TokensFrom( | ||||
|                         fillData.inputToken, | ||||
|                         msg.sender, | ||||
|                         provider, | ||||
| @@ -453,7 +470,7 @@ contract MultiplexFeature is | ||||
|                         _transferEth(payable(provider), outputTokenAmount); | ||||
|                         remainingEth -= outputTokenAmount; | ||||
|                     } else { | ||||
|                         _transferERC20Tokens( | ||||
|                         _transferERC20TokensFrom( | ||||
|                             IERC20TokenV06(fillData.tokens[i]), | ||||
|                             msg.sender, | ||||
|                             provider, | ||||
| @@ -512,7 +529,7 @@ contract MultiplexFeature is | ||||
|                     // send the output token to some address other than | ||||
|                     // msg.sender, so we must transfer the input token | ||||
|                     // to the FlashWallet here. | ||||
|                     _transferERC20Tokens( | ||||
|                     _transferERC20TokensFrom( | ||||
|                         args.inputToken, | ||||
|                         msg.sender, | ||||
|                         flashWallet, | ||||
| @@ -598,7 +615,7 @@ contract MultiplexFeature is | ||||
|  | ||||
|         if (pairAddress == address(0)) { | ||||
|             pairAddress = _computeUniswapPairAddress(tokens[0], tokens[1], isSushi); | ||||
|             _transferERC20Tokens( | ||||
|             _transferERC20TokensFrom( | ||||
|                 IERC20TokenV06(tokens[0]), | ||||
|                 msg.sender, | ||||
|                 pairAddress, | ||||
|   | ||||
							
								
								
									
										472
									
								
								contracts/zero-ex/contracts/src/features/OtcOrdersFeature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										472
									
								
								contracts/zero-ex/contracts/src/features/OtcOrdersFeature.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,472 @@ | ||||
| // 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/IEtherTokenV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; | ||||
| import "../errors/LibNativeOrdersRichErrors.sol"; | ||||
| import "../fixins/FixinCommon.sol"; | ||||
| import "../fixins/FixinEIP712.sol"; | ||||
| import "../fixins/FixinTokenSpender.sol"; | ||||
| import "../migrations/LibMigrate.sol"; | ||||
| import "../storage/LibNativeOrdersStorage.sol"; | ||||
| import "../storage/LibOtcOrdersStorage.sol"; | ||||
| import "./interfaces/IFeature.sol"; | ||||
| import "./interfaces/IOtcOrdersFeature.sol"; | ||||
| import "./libs/LibNativeOrder.sol"; | ||||
| import "./libs/LibSignature.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev Feature for interacting with OTC orders. | ||||
| contract OtcOrdersFeature is | ||||
|     IFeature, | ||||
|     IOtcOrdersFeature, | ||||
|     FixinCommon, | ||||
|     FixinEIP712, | ||||
|     FixinTokenSpender | ||||
| { | ||||
|     using LibSafeMathV06 for uint256; | ||||
|     using LibSafeMathV06 for uint128; | ||||
|  | ||||
|     /// @dev Options for handling ETH/WETH conversion | ||||
|     /// @param LeaveAsWeth Neither unwrap nor wrap. | ||||
|     /// @param WrapEth Wrap attached ETH. | ||||
|     /// @param UnwrapWeth Unwrap WETH before transferring | ||||
|     ///        to taker. | ||||
|     enum WethOptions { | ||||
|         LeaveAsWeth, | ||||
|         WrapEth, | ||||
|         UnwrapWeth | ||||
|     } | ||||
|  | ||||
|     /// @dev Name of this feature. | ||||
|     string public constant override FEATURE_NAME = "OtcOrders"; | ||||
|     /// @dev Version of this feature. | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0); | ||||
|     /// @dev The WETH token contract. | ||||
|     IEtherTokenV06 private immutable WETH; | ||||
|  | ||||
|     constructor(address zeroExAddress, IEtherTokenV06 weth) | ||||
|         public | ||||
|         FixinEIP712(zeroExAddress) | ||||
|     { | ||||
|         WETH = 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.fillOtcOrder.selector); | ||||
|         _registerFeatureFunction(this.fillOtcOrderWithEth.selector); | ||||
|         _registerFeatureFunction(this.fillTakerSignedOtcOrder.selector); | ||||
|         _registerFeatureFunction(this.getOtcOrderInfo.selector); | ||||
|         _registerFeatureFunction(this.getOtcOrderHash.selector); | ||||
|         _registerFeatureFunction(this.lastOtcTxOriginNonce.selector); | ||||
|         return LibMigrate.MIGRATE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @param takerTokenFillAmount Maximum taker token amount to fill this | ||||
|     ///        order with. | ||||
|     /// @param unwrapWeth Whether or not to unwrap bought WETH into ETH | ||||
|     ///        before transferring it to the taker. Should be set to false | ||||
|     ///        if the maker token is not WETH. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function fillOtcOrder( | ||||
|         LibNativeOrder.OtcOrder memory order, | ||||
|         LibSignature.Signature memory makerSignature, | ||||
|         uint128 takerTokenFillAmount, | ||||
|         bool unwrapWeth | ||||
|     ) | ||||
|         public | ||||
|         override | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) | ||||
|     { | ||||
|         if (!_isSenderValidTaker(order.taker)) { | ||||
|             bytes32 orderHash = getOtcOrderHash(order); | ||||
|             LibNativeOrdersRichErrors.OrderNotFillableByTakerError( | ||||
|                 orderHash, | ||||
|                 msg.sender, | ||||
|                 order.taker | ||||
|             ).rrevert(); | ||||
|         } | ||||
|         LibSignature.Signature memory nullSignature; | ||||
|         return _fillOtcOrderPrivate( | ||||
|             order, | ||||
|             makerSignature, | ||||
|             nullSignature, | ||||
|             takerTokenFillAmount, | ||||
|             unwrapWeth ? WethOptions.UnwrapWeth : WethOptions.LeaveAsWeth | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Fill an OTC order whose taker token is WETH for up | ||||
|     ///      to `msg.value`. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function fillOtcOrderWithEth( | ||||
|         LibNativeOrder.OtcOrder memory order, | ||||
|         LibSignature.Signature memory makerSignature | ||||
|     ) | ||||
|         public | ||||
|         override | ||||
|         payable | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) | ||||
|     { | ||||
|         if (!_isSenderValidTaker(order.taker)) { | ||||
|             bytes32 orderHash = getOtcOrderHash(order); | ||||
|             LibNativeOrdersRichErrors.OrderNotFillableByTakerError( | ||||
|                 orderHash, | ||||
|                 msg.sender, | ||||
|                 order.taker | ||||
|             ).rrevert(); | ||||
|         } | ||||
|         LibSignature.Signature memory nullSignature; | ||||
|         return _fillOtcOrderPrivate( | ||||
|             order, | ||||
|             makerSignature, | ||||
|             nullSignature, | ||||
|             msg.value.safeDowncastToUint128(), | ||||
|             WethOptions.WrapEth | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Fully fill an OTC order. "Meta-transaction" variant, | ||||
|     ///      requires order to be signed by both maker and taker. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @param takerSignature The order signature from the taker. | ||||
|     /// @param unwrapWeth Whether or not to unwrap bought WETH into ETH | ||||
|     ///        before transferring it to the taker. Should be set to false | ||||
|     ///        if the maker token is not WETH. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function fillTakerSignedOtcOrder( | ||||
|         LibNativeOrder.OtcOrder memory order, | ||||
|         LibSignature.Signature memory makerSignature, | ||||
|         LibSignature.Signature memory takerSignature, | ||||
|         bool unwrapWeth | ||||
|     ) | ||||
|         public | ||||
|         override | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) | ||||
|     { | ||||
|         return _fillOtcOrderPrivate( | ||||
|             order, | ||||
|             makerSignature, | ||||
|             takerSignature, | ||||
|             order.takerAmount, | ||||
|             unwrapWeth ? WethOptions.UnwrapWeth : WethOptions.LeaveAsWeth | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Fill an OTC order. Private variant. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @param takerSignature The order signature from the taker. | ||||
|     ///        Ignored if msg.sender == order.taker. | ||||
|     /// @param takerTokenFillAmount Maximum taker token amount to | ||||
|     ///        fill this order with. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function _fillOtcOrderPrivate( | ||||
|         LibNativeOrder.OtcOrder memory order, | ||||
|         LibSignature.Signature memory makerSignature, | ||||
|         LibSignature.Signature memory takerSignature, | ||||
|         uint128 takerTokenFillAmount, | ||||
|         WethOptions wethOptions | ||||
|     ) | ||||
|         private | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) | ||||
|     { | ||||
|         LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order); | ||||
|  | ||||
|         // Must be fillable. | ||||
|         if (orderInfo.status != LibNativeOrder.OrderStatus.FILLABLE) { | ||||
|             LibNativeOrdersRichErrors.OrderNotFillableError( | ||||
|                 orderInfo.orderHash, | ||||
|                 uint8(orderInfo.status) | ||||
|             ).rrevert(); | ||||
|         } | ||||
|  | ||||
|         address taker = msg.sender; | ||||
|         { | ||||
|             LibNativeOrdersStorage.Storage storage stor = | ||||
|                 LibNativeOrdersStorage.getStorage(); | ||||
|  | ||||
|             // Must be fillable by the tx.origin. | ||||
|             if ( | ||||
|                 order.txOrigin != tx.origin && | ||||
|                 !stor.originRegistry[order.txOrigin][tx.origin] | ||||
|             ) { | ||||
|                 LibNativeOrdersRichErrors.OrderNotFillableByOriginError( | ||||
|                     orderInfo.orderHash, | ||||
|                     tx.origin, | ||||
|                     order.txOrigin | ||||
|                 ).rrevert(); | ||||
|             } | ||||
|  | ||||
|             // Maker signature must be valid for the order. | ||||
|             address makerSigner = LibSignature.getSignerOfHash(orderInfo.orderHash, makerSignature); | ||||
|             if ( | ||||
|                 makerSigner != order.maker && | ||||
|                 !stor.orderSignerRegistry[order.maker][makerSigner] | ||||
|             ) { | ||||
|                 LibNativeOrdersRichErrors.OrderNotSignedByMakerError( | ||||
|                     orderInfo.orderHash, | ||||
|                     makerSigner, | ||||
|                     order.maker | ||||
|                 ).rrevert(); | ||||
|             } | ||||
|  | ||||
|             // If msg.sender is not the taker, validate the taker signature. | ||||
|             if (!_isSenderValidTaker(order.taker)) { | ||||
|                 address takerSigner = LibSignature.getSignerOfHash(orderInfo.orderHash, takerSignature); | ||||
|                 if ( | ||||
|                     takerSigner != order.taker && | ||||
|                     !stor.orderSignerRegistry[order.taker][takerSigner] | ||||
|                 ) { | ||||
|                     LibNativeOrdersRichErrors.OrderNotSignedByTakerError( | ||||
|                         orderInfo.orderHash, | ||||
|                         takerSigner, | ||||
|                         order.taker | ||||
|                     ).rrevert(); | ||||
|                 } | ||||
|                 taker = order.taker; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Settle between the maker and taker. | ||||
|         (takerTokenFilledAmount, makerTokenFilledAmount) = _settleOtcOrder( | ||||
|             order, | ||||
|             taker, | ||||
|             takerTokenFillAmount, | ||||
|             wethOptions | ||||
|         ); | ||||
|  | ||||
|         emit OtcOrderFilled( | ||||
|             orderInfo.orderHash, | ||||
|             order.maker, | ||||
|             taker, | ||||
|             address(order.makerToken), | ||||
|             address(order.takerToken), | ||||
|             takerTokenFilledAmount, | ||||
|             makerTokenFilledAmount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Settle the trade between an OTC order's maker and taker. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param takerTokenFillAmount Maximum taker token amount to fill this | ||||
|     ///        order with. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function _settleOtcOrder( | ||||
|         LibNativeOrder.OtcOrder memory order, | ||||
|         address taker, | ||||
|         uint128 takerTokenFillAmount, | ||||
|         WethOptions wethOptions | ||||
|     ) | ||||
|         private | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) | ||||
|     { | ||||
|         { | ||||
|             // Unpack nonce fields | ||||
|             uint64 nonceBucket = uint64(order.expiryAndNonce >> 128); | ||||
|             uint128 nonce = uint128(order.expiryAndNonce); | ||||
|             // Update tx origin nonce for the order | ||||
|             LibOtcOrdersStorage.getStorage().txOriginNonces | ||||
|                 [order.txOrigin][nonceBucket] = nonce; | ||||
|         } | ||||
|  | ||||
|         if (takerTokenFillAmount == order.takerAmount) { | ||||
|             takerTokenFilledAmount = order.takerAmount; | ||||
|             makerTokenFilledAmount = order.makerAmount; | ||||
|         } else { | ||||
|             // Clamp the taker token fill amount to the fillable amount. | ||||
|             takerTokenFilledAmount = LibSafeMathV06.min128( | ||||
|                 takerTokenFillAmount, | ||||
|                 order.takerAmount | ||||
|             ); | ||||
|             // Compute the maker token amount. | ||||
|             // This should never overflow because the values are all clamped to | ||||
|             // (2^128-1). | ||||
|             makerTokenFilledAmount = uint128(LibMathV06.getPartialAmountFloor( | ||||
|                 uint256(takerTokenFilledAmount), | ||||
|                 uint256(order.takerAmount), | ||||
|                 uint256(order.makerAmount) | ||||
|             )); | ||||
|         } | ||||
|  | ||||
|         if (wethOptions == WethOptions.WrapEth) { | ||||
|             require( | ||||
|                 order.takerToken == WETH, | ||||
|                 "OtcOrdersFeature/INVALID_WRAP_ETH" | ||||
|             ); | ||||
|             // Wrap ETH | ||||
|             WETH.deposit{value: takerTokenFilledAmount}(); | ||||
|             // Transfer WETH to maker | ||||
|             WETH.transfer(order.maker, takerTokenFilledAmount); | ||||
|             if (takerTokenFilledAmount < msg.value) { | ||||
|                 // Refund unused ETH | ||||
|                 _transferEth( | ||||
|                     msg.sender, | ||||
|                     msg.value - uint256(takerTokenFilledAmount) | ||||
|                 ); | ||||
|             } | ||||
|         } else { | ||||
|             // Transfer taker -> maker | ||||
|             _transferERC20TokensFrom( | ||||
|                 order.takerToken, | ||||
|                 taker, | ||||
|                 order.maker, | ||||
|                 takerTokenFilledAmount | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         if (wethOptions == WethOptions.UnwrapWeth) { | ||||
|             require( | ||||
|                 order.makerToken == WETH, | ||||
|                 "OtcOrdersFeature/INVALID_UNWRAP_WETH" | ||||
|             ); | ||||
|             // Transfer maker tokens in | ||||
|             _transferERC20TokensFrom( | ||||
|                 order.makerToken, | ||||
|                 order.maker, | ||||
|                 address(this), | ||||
|                 makerTokenFilledAmount | ||||
|             ); | ||||
|             // Unwrap WETH | ||||
|             WETH.withdraw(makerTokenFilledAmount); | ||||
|             // Transfer ETH to taker | ||||
|             _transferEth(taker, makerTokenFilledAmount); | ||||
|         } else { | ||||
|             // Transfer maker -> taker. | ||||
|             _transferERC20TokensFrom( | ||||
|                 order.makerToken, | ||||
|                 order.maker, | ||||
|                 taker, | ||||
|                 makerTokenFilledAmount | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the order info for an OTC order. | ||||
|     /// @param order The OTC order. | ||||
|     /// @return orderInfo Info about the order. | ||||
|     function getOtcOrderInfo(LibNativeOrder.OtcOrder memory order) | ||||
|         public | ||||
|         override | ||||
|         view | ||||
|         returns (LibNativeOrder.OtcOrderInfo memory orderInfo) | ||||
|     { | ||||
|         // compute order hash. | ||||
|         orderInfo.orderHash = getOtcOrderHash(order); | ||||
|  | ||||
|         LibOtcOrdersStorage.Storage storage stor = | ||||
|             LibOtcOrdersStorage.getStorage(); | ||||
|  | ||||
|         // Unpack expiry and nonce fields | ||||
|         uint64 expiry = uint64(order.expiryAndNonce >> 192); | ||||
|         uint64 nonceBucket = uint64(order.expiryAndNonce >> 128); | ||||
|         uint128 nonce = uint128(order.expiryAndNonce); | ||||
|  | ||||
|         // check tx origin nonce | ||||
|         uint128 lastNonce = stor.txOriginNonces | ||||
|             [order.txOrigin] | ||||
|             [nonceBucket]; | ||||
|         if (nonce <= lastNonce) { | ||||
|             orderInfo.status = LibNativeOrder.OrderStatus.INVALID; | ||||
|             return orderInfo; | ||||
|         } | ||||
|  | ||||
|         // Check for expiration. | ||||
|         if (expiry <= uint64(block.timestamp)) { | ||||
|             orderInfo.status = LibNativeOrder.OrderStatus.EXPIRED; | ||||
|             return orderInfo; | ||||
|         } | ||||
|  | ||||
|         orderInfo.status = LibNativeOrder.OrderStatus.FILLABLE; | ||||
|         return orderInfo; | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the canonical hash of an OTC order. | ||||
|     /// @param order The OTC order. | ||||
|     /// @return orderHash The order hash. | ||||
|     function getOtcOrderHash(LibNativeOrder.OtcOrder memory order) | ||||
|         public | ||||
|         override | ||||
|         view | ||||
|         returns (bytes32 orderHash) | ||||
|     { | ||||
|         return _getEIP712Hash( | ||||
|             LibNativeOrder.getOtcOrderStructHash(order) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the last nonce used for a particular | ||||
|     ///      tx.origin address and nonce bucket. | ||||
|     /// @param txOrigin The address. | ||||
|     /// @param nonceBucket The nonce bucket index. | ||||
|     /// @return lastNonce The last nonce value used. | ||||
|     function lastOtcTxOriginNonce(address txOrigin, uint64 nonceBucket) | ||||
|         public | ||||
|         override | ||||
|         view | ||||
|         returns (uint128 lastNonce) | ||||
|     { | ||||
|         LibOtcOrdersStorage.Storage storage stor = | ||||
|             LibOtcOrdersStorage.getStorage(); | ||||
|         return stor.txOriginNonces | ||||
|             [txOrigin] | ||||
|             [nonceBucket]; | ||||
|     } | ||||
|  | ||||
|     function _transferEth(address recipient, uint256 amount) | ||||
|         private | ||||
|     { | ||||
|         // Transfer ETH to recipient | ||||
|         (bool success, bytes memory revertData) = | ||||
|             recipient.call{value: amount}(""); | ||||
|         // Revert on failure | ||||
|         if (!success) { | ||||
|             revertData.rrevert(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function _isSenderValidTaker(address orderTaker) | ||||
|         private | ||||
|         view | ||||
|         returns (bool) | ||||
|     { | ||||
|         return orderTaker == address(0) || orderTaker == msg.sender; | ||||
|     } | ||||
| } | ||||
| @@ -312,7 +312,7 @@ contract TransformERC20Feature is | ||||
|         // Transfer input tokens. | ||||
|         if (!LibERC20Transformer.isTokenETH(inputToken) && amount != 0) { | ||||
|             // Token is not ETH, so pull ERC20 tokens. | ||||
|             _transferERC20Tokens( | ||||
|             _transferERC20TokensFrom( | ||||
|                 inputToken, | ||||
|                 from, | ||||
|                 to, | ||||
|   | ||||
							
								
								
									
										419
									
								
								contracts/zero-ex/contracts/src/features/UniswapV3Feature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										419
									
								
								contracts/zero-ex/contracts/src/features/UniswapV3Feature.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,419 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| /* | ||||
|  | ||||
|   Copyright 2021 ZeroEx Intl. | ||||
|  | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
|   You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|   Unless required by applicable law or agreed to in writing, software | ||||
|   distributed under the License is distributed on an "AS IS" BASIS, | ||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|   See the License for the specific language governing permissions and | ||||
|   limitations under the License. | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.6.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol"; | ||||
| import "../vendor/IUniswapV3Pool.sol"; | ||||
| import "../migrations/LibMigrate.sol"; | ||||
| import "../fixins/FixinCommon.sol"; | ||||
| import "../fixins/FixinTokenSpender.sol"; | ||||
| import "./interfaces/IFeature.sol"; | ||||
| import "./interfaces/IUniswapV3Feature.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev VIP uniswap fill functions. | ||||
| contract UniswapV3Feature is | ||||
|     IFeature, | ||||
|     IUniswapV3Feature, | ||||
|     FixinCommon, | ||||
|     FixinTokenSpender | ||||
| { | ||||
|     /// @dev Name of this feature. | ||||
|     string public constant override FEATURE_NAME = "UniswapV3Feature"; | ||||
|     /// @dev Version of this feature. | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0); | ||||
|     /// @dev WETH contract. | ||||
|     IEtherTokenV06 private immutable WETH; | ||||
|     /// @dev UniswapV3 Factory contract address prepended with '0xff' and left-aligned. | ||||
|     bytes32 private immutable UNI_FF_FACTORY_ADDRESS; | ||||
|     /// @dev UniswapV3 pool init code hash. | ||||
|     bytes32 private immutable UNI_POOL_INIT_CODE_HASH; | ||||
|     /// @dev Minimum size of an encoded swap path: | ||||
|     ///      sizeof(address(inputToken) | uint24(fee) | address(outputToken)) | ||||
|     uint256 private constant SINGLE_HOP_PATH_SIZE = 20 + 3 + 20; | ||||
|     /// @dev How many bytes to skip ahead in an encoded path to start at the next hop: | ||||
|     ///      sizeof(address(inputToken) | uint24(fee)) | ||||
|     uint256 private constant PATH_SKIP_HOP_SIZE = 20 + 3; | ||||
|     /// @dev The size of the swap callback data. | ||||
|     uint256 private constant SWAP_CALLBACK_DATA_SIZE = 128; | ||||
|     /// @dev Minimum tick price sqrt ratio. | ||||
|     uint160 internal constant MIN_PRICE_SQRT_RATIO = 4295128739; | ||||
|     /// @dev Minimum tick price sqrt ratio. | ||||
|     uint160 internal constant MAX_PRICE_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; | ||||
|     /// @dev Mask of lower 20 bytes. | ||||
|     uint256 private constant ADDRESS_MASK = 0x00ffffffffffffffffffffffffffffffffffffffff; | ||||
|     /// @dev Mask of lower 3 bytes. | ||||
|     uint256 private constant UINT24_MASK = 0xffffff; | ||||
|  | ||||
|     /// @dev Construct this contract. | ||||
|     /// @param weth The WETH contract. | ||||
|     /// @param uniFactory The UniswapV3 factory contract. | ||||
|     /// @param poolInitCodeHash The UniswapV3 pool init code hash. | ||||
|     constructor( | ||||
|         IEtherTokenV06 weth, | ||||
|         address uniFactory, | ||||
|         bytes32 poolInitCodeHash | ||||
|     ) public { | ||||
|         WETH = weth; | ||||
|         UNI_FF_FACTORY_ADDRESS = bytes32((uint256(0xff) << 248) | (uint256(uniFactory) << 88)); | ||||
|         UNI_POOL_INIT_CODE_HASH = poolInitCodeHash; | ||||
|     } | ||||
|  | ||||
|     /// @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.sellEthForTokenToUniswapV3.selector); | ||||
|         _registerFeatureFunction(this.sellTokenForEthToUniswapV3.selector); | ||||
|         _registerFeatureFunction(this.sellTokenForTokenToUniswapV3.selector); | ||||
|         _registerFeatureFunction(this.uniswapV3SwapCallback.selector); | ||||
|         return LibMigrate.MIGRATE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev Sell attached ETH directly against uniswap v3. | ||||
|     /// @param encodedPath Uniswap-encoded path, where the first token is WETH. | ||||
|     /// @param recipient The recipient of the bought tokens. Can be zero for sender. | ||||
|     /// @param minBuyAmount Minimum amount of the last token in the path to buy. | ||||
|     /// @return buyAmount Amount of the last token in the path bought. | ||||
|     function sellEthForTokenToUniswapV3( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 minBuyAmount, | ||||
|         address recipient | ||||
|     ) | ||||
|         public | ||||
|         payable | ||||
|         override | ||||
|         returns (uint256 buyAmount) | ||||
|     { | ||||
|         // Wrap ETH. | ||||
|         WETH.deposit{ value: msg.value }(); | ||||
|         return _swap( | ||||
|             encodedPath, | ||||
|             msg.value, | ||||
|             minBuyAmount, | ||||
|             address(this), // we are payer because we hold the WETH | ||||
|             _normalizeRecipient(recipient) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Sell a token for ETH directly against uniswap v3. | ||||
|     /// @param encodedPath Uniswap-encoded path, where the last token is WETH. | ||||
|     /// @param sellAmount amount of the first token in the path to sell. | ||||
|     /// @param minBuyAmount Minimum amount of ETH to buy. | ||||
|     /// @param recipient The recipient of the bought tokens. Can be zero for sender. | ||||
|     /// @return buyAmount Amount of ETH bought. | ||||
|     function sellTokenForEthToUniswapV3( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBuyAmount, | ||||
|         address payable recipient | ||||
|     ) | ||||
|         public | ||||
|         override | ||||
|         returns (uint256 buyAmount) | ||||
|     { | ||||
|         buyAmount = _swap( | ||||
|             encodedPath, | ||||
|             sellAmount, | ||||
|             minBuyAmount, | ||||
|             msg.sender, | ||||
|             address(this) // we are recipient because we need to unwrap WETH | ||||
|         ); | ||||
|         WETH.withdraw(buyAmount); | ||||
|         // Transfer ETH to recipient. | ||||
|         (bool success, bytes memory revertData) = | ||||
|             _normalizeRecipient(recipient).call{ value: buyAmount }(""); | ||||
|         if (!success) { | ||||
|             revertData.rrevert(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Sell a token for another token directly against uniswap v3. | ||||
|     /// @param encodedPath Uniswap-encoded path. | ||||
|     /// @param sellAmount amount of the first token in the path to sell. | ||||
|     /// @param minBuyAmount Minimum amount of the last token in the path to buy. | ||||
|     /// @param recipient The recipient of the bought tokens. Can be zero for sender. | ||||
|     /// @return buyAmount Amount of the last token in the path bought. | ||||
|     function sellTokenForTokenToUniswapV3( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBuyAmount, | ||||
|         address recipient | ||||
|     ) | ||||
|         public | ||||
|         override | ||||
|         returns (uint256 buyAmount) | ||||
|     { | ||||
|         buyAmount = _swap( | ||||
|             encodedPath, | ||||
|             sellAmount, | ||||
|             minBuyAmount, | ||||
|             msg.sender, | ||||
|             _normalizeRecipient(recipient) | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev The UniswapV3 pool swap callback which pays the funds requested | ||||
|     ///      by the caller/pool to the pool. Can only be called by a valid | ||||
|     ///      UniswapV3 pool. | ||||
|     /// @param amount0Delta Token0 amount owed. | ||||
|     /// @param amount1Delta Token1 amount owed. | ||||
|     /// @param data Arbitrary data forwarded from swap() caller. An ABI-encoded | ||||
|     ///        struct of: inputToken, outputToken, fee, payer | ||||
|     function uniswapV3SwapCallback( | ||||
|         int256 amount0Delta, | ||||
|         int256 amount1Delta, | ||||
|         bytes calldata data | ||||
|     ) | ||||
|         external | ||||
|         override | ||||
|     { | ||||
|         IERC20TokenV06 token0; | ||||
|         IERC20TokenV06 token1; | ||||
|         address payer; | ||||
|         { | ||||
|             uint24 fee; | ||||
|             // Decode the data. | ||||
|             require(data.length == SWAP_CALLBACK_DATA_SIZE, "UniswapFeature/INVALID_SWAP_CALLBACK_DATA"); | ||||
|             assembly { | ||||
|                 let p := add(36, calldataload(68)) | ||||
|                 token0 := calldataload(p) | ||||
|                 token1 := calldataload(add(p, 32)) | ||||
|                 fee := calldataload(add(p, 64)) | ||||
|                 payer := calldataload(add(p, 96)) | ||||
|             } | ||||
|             (token0, token1) = token0 < token1 | ||||
|                 ? (token0, token1) | ||||
|                 : (token1, token0); | ||||
|             // Only a valid pool contract can call this function. | ||||
|             require( | ||||
|                 msg.sender == address(_toPool(token0, fee, token1)), | ||||
|                 "UniswapV3Feature/INVALID_SWAP_CALLBACK_CALLER" | ||||
|             ); | ||||
|         } | ||||
|         // Pay the amount owed to the pool. | ||||
|         if (amount0Delta > 0) { | ||||
|             _pay(token0, payer, msg.sender, uint256(amount0Delta)); | ||||
|         } else if (amount1Delta > 0) { | ||||
|             _pay(token1, payer, msg.sender, uint256(amount1Delta)); | ||||
|         } else { | ||||
|             revert("UniswapV3Feature/INVALID_SWAP_AMOUNTS"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Executes successive swaps along an encoded uniswap path. | ||||
|     function _swap( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBuyAmount, | ||||
|         address payer, | ||||
|         address recipient | ||||
|     ) | ||||
|         private | ||||
|         returns (uint256 buyAmount) | ||||
|     { | ||||
|         if (sellAmount != 0) { | ||||
|             require(sellAmount <= uint256(type(int256).max), "UniswapV3Feature/SELL_AMOUNT_OVERFLOW"); | ||||
|  | ||||
|             // Perform a swap for each hop in the path. | ||||
|             bytes memory swapCallbackData = new bytes(SWAP_CALLBACK_DATA_SIZE); | ||||
|             while (true) { | ||||
|                 bool isPathMultiHop = _isPathMultiHop(encodedPath); | ||||
|                 bool zeroForOne; | ||||
|                 IUniswapV3Pool pool; | ||||
|                 { | ||||
|                     ( | ||||
|                         IERC20TokenV06 inputToken, | ||||
|                         uint24 fee, | ||||
|                         IERC20TokenV06 outputToken | ||||
|                     ) = _decodeFirstPoolInfoFromPath(encodedPath); | ||||
|                     pool = _toPool(inputToken, fee, outputToken); | ||||
|                     zeroForOne = inputToken < outputToken; | ||||
|                     _updateSwapCallbackData( | ||||
|                         swapCallbackData, | ||||
|                         inputToken, | ||||
|                         outputToken, | ||||
|                         fee, | ||||
|                         payer | ||||
|                     ); | ||||
|                 } | ||||
|                 (int256 amount0, int256 amount1) = pool.swap( | ||||
|                     // Intermediate tokens go to this contract. | ||||
|                     isPathMultiHop ? address(this) : recipient, | ||||
|                     zeroForOne, | ||||
|                     int256(sellAmount), | ||||
|                     zeroForOne | ||||
|                         ? MIN_PRICE_SQRT_RATIO + 1 | ||||
|                         : MAX_PRICE_SQRT_RATIO - 1, | ||||
|                     swapCallbackData | ||||
|                 ); | ||||
|                 { | ||||
|                     int256 _buyAmount = -(zeroForOne ? amount1 : amount0); | ||||
|                     require(_buyAmount >= 0, "UniswapV3Feature/INVALID_BUY_AMOUNT"); | ||||
|                     buyAmount = uint256(_buyAmount); | ||||
|                 } | ||||
|                 if (!isPathMultiHop) { | ||||
|                     // Done. | ||||
|                     break; | ||||
|                 } | ||||
|                 // Continue with next hop. | ||||
|                 payer = address(this); // Subsequent hops are paid for by us. | ||||
|                 sellAmount = buyAmount; | ||||
|                 // Skip to next hop along path. | ||||
|                 encodedPath = _shiftHopFromPathInPlace(encodedPath); | ||||
|             } | ||||
|         } | ||||
|         require(minBuyAmount <= buyAmount, "UniswapV3Feature/UNDERBOUGHT"); | ||||
|     } | ||||
|  | ||||
|     // Pay tokens from `payer` to `to`, using `transferFrom()` if | ||||
|     // `payer` != this contract. | ||||
|     function _pay( | ||||
|         IERC20TokenV06 token, | ||||
|         address payer, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         private | ||||
|     { | ||||
|         if (payer != address(this)) { | ||||
|             _transferERC20TokensFrom(token, payer, to, amount); | ||||
|         } else { | ||||
|             _transferERC20Tokens(token, to, amount); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Update `swapCallbackData` in place with new values. | ||||
|     function _updateSwapCallbackData( | ||||
|         bytes memory swapCallbackData, | ||||
|         IERC20TokenV06 inputToken, | ||||
|         IERC20TokenV06 outputToken, | ||||
|         uint24 fee, | ||||
|         address payer | ||||
|     ) | ||||
|         private | ||||
|         pure | ||||
|     { | ||||
|         assembly { | ||||
|             let p := add(swapCallbackData, 32) | ||||
|             mstore(p, inputToken) | ||||
|             mstore(add(p, 32), outputToken) | ||||
|             mstore(add(p, 64), and(UINT24_MASK, fee)) | ||||
|             mstore(add(p, 96), and(ADDRESS_MASK, payer)) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Compute the pool address given two tokens and a fee. | ||||
|     function _toPool( | ||||
|         IERC20TokenV06 inputToken, | ||||
|         uint24 fee, | ||||
|         IERC20TokenV06 outputToken | ||||
|     ) | ||||
|         private | ||||
|         view | ||||
|         returns (IUniswapV3Pool pool) | ||||
|     { | ||||
|         // address(keccak256(abi.encodePacked( | ||||
|         //     hex"ff", | ||||
|         //     UNI_FACTORY_ADDRESS, | ||||
|         //     keccak256(abi.encode(inputToken, outputToken, fee)), | ||||
|         //     UNI_POOL_INIT_CODE_HASH | ||||
|         // ))) | ||||
|         bytes32 ffFactoryAddress = UNI_FF_FACTORY_ADDRESS; | ||||
|         bytes32 poolInitCodeHash = UNI_POOL_INIT_CODE_HASH; | ||||
|         (IERC20TokenV06 token0, IERC20TokenV06 token1) = inputToken < outputToken | ||||
|             ? (inputToken, outputToken) | ||||
|             : (outputToken, inputToken); | ||||
|         assembly { | ||||
|             let s := mload(0x40) | ||||
|             let p := s | ||||
|             mstore(p, ffFactoryAddress) | ||||
|             p := add(p, 21) | ||||
|             // Compute the inner hash in-place | ||||
|                 mstore(p, token0) | ||||
|                 mstore(add(p, 32), token1) | ||||
|                 mstore(add(p, 64), and(UINT24_MASK, fee)) | ||||
|                 mstore(p, keccak256(p, 96)) | ||||
|             p := add(p, 32) | ||||
|             mstore(p, poolInitCodeHash) | ||||
|             pool := and(ADDRESS_MASK, keccak256(s, 85)) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Return whether or not an encoded uniswap path contains more than one hop. | ||||
|     function _isPathMultiHop(bytes memory encodedPath) | ||||
|         private | ||||
|         pure | ||||
|         returns (bool isMultiHop) | ||||
|     { | ||||
|         return encodedPath.length > SINGLE_HOP_PATH_SIZE; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // Return the first input token, output token, and fee of an encoded uniswap path. | ||||
|     function _decodeFirstPoolInfoFromPath(bytes memory encodedPath) | ||||
|         private | ||||
|         pure | ||||
|         returns ( | ||||
|             IERC20TokenV06 inputToken, | ||||
|             uint24 fee, | ||||
|             IERC20TokenV06 outputToken | ||||
|         ) | ||||
|     { | ||||
|         require(encodedPath.length >= SINGLE_HOP_PATH_SIZE, "UniswapV3Feature/BAD_PATH_ENCODING"); | ||||
|         assembly { | ||||
|             let p := add(encodedPath, 32) | ||||
|             inputToken := shr(96, mload(p)) | ||||
|             p := add(p, 20) | ||||
|             fee := shr(232, mload(p)) | ||||
|             p := add(p, 3) | ||||
|             outputToken := shr(96, mload(p)) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Skip past the first hop of an encoded uniswap path in-place. | ||||
|     function _shiftHopFromPathInPlace(bytes memory encodedPath) | ||||
|         private | ||||
|         pure | ||||
|         returns (bytes memory shiftedEncodedPath) | ||||
|     { | ||||
|         require(encodedPath.length >= PATH_SKIP_HOP_SIZE, "UniswapV3Feature/BAD_PATH_ENCODING"); | ||||
|         uint256 shiftSize = PATH_SKIP_HOP_SIZE; | ||||
|         uint256 newSize = encodedPath.length - shiftSize; | ||||
|         assembly { | ||||
|             shiftedEncodedPath := add(encodedPath, shiftSize) | ||||
|             mstore(shiftedEncodedPath, newSize) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Convert null address values to msg.sender. | ||||
|     function _normalizeRecipient(address recipient) | ||||
|         private | ||||
|         view | ||||
|         returns (address payable normalizedRecipient) | ||||
|     { | ||||
|         return recipient == address(0) ? msg.sender : payable(recipient); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,122 @@ | ||||
| // 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 "../libs/LibNativeOrder.sol"; | ||||
| import "../libs/LibSignature.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev Feature for interacting with OTC orders. | ||||
| interface IOtcOrdersFeature { | ||||
|  | ||||
|     /// @dev Emitted whenever an `OtcOrder` is filled. | ||||
|     /// @param orderHash The canonical hash of the order. | ||||
|     /// @param maker The maker of the order. | ||||
|     /// @param taker The taker of the order. | ||||
|     /// @param takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @param makerTokenFilledAmount How much maker token was filled. | ||||
|     event OtcOrderFilled( | ||||
|         bytes32 orderHash, | ||||
|         address maker, | ||||
|         address taker, | ||||
|         address makerToken, | ||||
|         address takerToken, | ||||
|         uint128 takerTokenFilledAmount, | ||||
|         uint128 makerTokenFilledAmount | ||||
|     ); | ||||
|  | ||||
|     /// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @param takerTokenFillAmount Maximum taker token amount to fill this | ||||
|     ///        order with. | ||||
|     /// @param unwrapWeth Whether or not to unwrap bought WETH into ETH | ||||
|     ///        before transferring it to the taker. Should be set to false | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function fillOtcOrder( | ||||
|         LibNativeOrder.OtcOrder calldata order, | ||||
|         LibSignature.Signature calldata makerSignature, | ||||
|         uint128 takerTokenFillAmount, | ||||
|         bool unwrapWeth | ||||
|     ) | ||||
|         external | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount); | ||||
|  | ||||
|     /// @dev Fill an OTC order whose taker token is WETH for up | ||||
|     ///      to `msg.value`. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function fillOtcOrderWithEth( | ||||
|         LibNativeOrder.OtcOrder calldata order, | ||||
|         LibSignature.Signature calldata makerSignature | ||||
|     ) | ||||
|         external | ||||
|         payable | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount); | ||||
|  | ||||
|     /// @dev Fully fill an OTC order. "Meta-transaction" variant, | ||||
|     ///      requires order to be signed by both maker and taker. | ||||
|     /// @param order The OTC order. | ||||
|     /// @param makerSignature The order signature from the maker. | ||||
|     /// @param takerSignature The order signature from the taker. | ||||
|     /// @param unwrapWeth Whether or not to unwrap bought WETH into ETH | ||||
|     ///        before transferring it to the taker. Should be set to false | ||||
|     ///        if the maker token is not WETH. | ||||
|     /// @return takerTokenFilledAmount How much taker token was filled. | ||||
|     /// @return makerTokenFilledAmount How much maker token was filled. | ||||
|     function fillTakerSignedOtcOrder( | ||||
|         LibNativeOrder.OtcOrder calldata order, | ||||
|         LibSignature.Signature calldata makerSignature, | ||||
|         LibSignature.Signature calldata takerSignature, | ||||
|         bool unwrapWeth | ||||
|     ) | ||||
|         external | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount); | ||||
|  | ||||
|     /// @dev Get the order info for an OTC order. | ||||
|     /// @param order The OTC order. | ||||
|     /// @return orderInfo Info about the order. | ||||
|     function getOtcOrderInfo(LibNativeOrder.OtcOrder calldata order) | ||||
|         external | ||||
|         view | ||||
|         returns (LibNativeOrder.OtcOrderInfo memory orderInfo); | ||||
|  | ||||
|     /// @dev Get the canonical hash of an OTC order. | ||||
|     /// @param order The OTC order. | ||||
|     /// @return orderHash The order hash. | ||||
|     function getOtcOrderHash(LibNativeOrder.OtcOrder calldata order) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes32 orderHash); | ||||
|  | ||||
|     /// @dev Get the last nonce used for a particular | ||||
|     ///      tx.origin address and nonce bucket. | ||||
|     /// @param txOrigin The address. | ||||
|     /// @param nonceBucket The nonce bucket index. | ||||
|     /// @return lastNonce The last nonce value used. | ||||
|     function lastOtcTxOriginNonce(address txOrigin, uint64 nonceBucket) | ||||
|         external | ||||
|         view | ||||
|         returns (uint128 lastNonce); | ||||
| } | ||||
| @@ -0,0 +1,86 @@ | ||||
| // 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/IERC20TokenV06.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev VIP uniswap v3 fill functions. | ||||
| interface IUniswapV3Feature { | ||||
|  | ||||
|     /// @dev Sell attached ETH directly against uniswap v3. | ||||
|     /// @param encodedPath Uniswap-encoded path, where the first token is WETH. | ||||
|     /// @param minBuyAmount Minimum amount of the last token in the path to buy. | ||||
|     /// @param recipient The recipient of the bought tokens. Can be zero for sender. | ||||
|     /// @return buyAmount Amount of the last token in the path bought. | ||||
|     function sellEthForTokenToUniswapV3( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 minBuyAmount, | ||||
|         address recipient | ||||
|     ) | ||||
|         external | ||||
|         payable | ||||
|         returns (uint256 buyAmount); | ||||
|  | ||||
|     /// @dev Sell a token for ETH directly against uniswap v3. | ||||
|     /// @param encodedPath Uniswap-encoded path, where the last token is WETH. | ||||
|     /// @param sellAmount amount of the first token in the path to sell. | ||||
|     /// @param minBuyAmount Minimum amount of ETH to buy. | ||||
|     /// @param recipient The recipient of the bought tokens. Can be zero for sender. | ||||
|     /// @return buyAmount Amount of ETH bought. | ||||
|     function sellTokenForEthToUniswapV3( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBuyAmount, | ||||
|         address payable recipient | ||||
|     ) | ||||
|         external | ||||
|         returns (uint256 buyAmount); | ||||
|  | ||||
|     /// @dev Sell a token for another token directly against uniswap v3. | ||||
|     /// @param encodedPath Uniswap-encoded path. | ||||
|     /// @param sellAmount amount of the first token in the path to sell. | ||||
|     /// @param minBuyAmount Minimum amount of the last token in the path to buy. | ||||
|     /// @param recipient The recipient of the bought tokens. Can be zero for sender. | ||||
|     /// @return buyAmount Amount of the last token in the path bought. | ||||
|     function sellTokenForTokenToUniswapV3( | ||||
|         bytes memory encodedPath, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBuyAmount, | ||||
|         address recipient | ||||
|     ) | ||||
|         external | ||||
|         returns (uint256 buyAmount); | ||||
|  | ||||
|     /// @dev The UniswapV3 pool swap callback which pays the funds requested | ||||
|     ///      by the caller/pool to the pool. Can only be called by a valid | ||||
|     ///      UniswapV3 pool. | ||||
|     /// @param amount0Delta Token0 amount owed. | ||||
|     /// @param amount1Delta Token1 amount owed. | ||||
|     /// @param data Arbitrary data forwarded from swap() caller. An ABI-encoded | ||||
|     ///        struct of: inputToken, outputToken, fee, payer | ||||
|     function uniswapV3SwapCallback( | ||||
|         int256 amount0Delta, | ||||
|         int256 amount1Delta, | ||||
|         bytes calldata data | ||||
|     ) | ||||
|         external; | ||||
| } | ||||
| @@ -69,6 +69,18 @@ library LibNativeOrder { | ||||
|         uint256 salt; | ||||
|     } | ||||
|  | ||||
|     /// @dev An OTC limit order. | ||||
|     struct OtcOrder { | ||||
|         IERC20TokenV06 makerToken; | ||||
|         IERC20TokenV06 takerToken; | ||||
|         uint128 makerAmount; | ||||
|         uint128 takerAmount; | ||||
|         address maker; | ||||
|         address taker; | ||||
|         address txOrigin; | ||||
|         uint256 expiryAndNonce; // [uint64 expiry, uint64 nonceBucket, uint128 nonce] | ||||
|     } | ||||
|  | ||||
|     /// @dev Info on a limit or RFQ order. | ||||
|     struct OrderInfo { | ||||
|         bytes32 orderHash; | ||||
| @@ -76,6 +88,12 @@ library LibNativeOrder { | ||||
|         uint128 takerTokenFilledAmount; | ||||
|     } | ||||
|  | ||||
|     /// @dev Info on an OTC order. | ||||
|     struct OtcOrderInfo { | ||||
|         bytes32 orderHash; | ||||
|         OrderStatus status; | ||||
|     } | ||||
|  | ||||
|     uint256 private constant UINT_128_MASK = (1 << 128) - 1; | ||||
|     uint256 private constant UINT_64_MASK = (1 << 64) - 1; | ||||
|     uint256 private constant ADDRESS_MASK = (1 << 160) - 1; | ||||
| @@ -118,6 +136,22 @@ library LibNativeOrder { | ||||
|     uint256 private constant _RFQ_ORDER_TYPEHASH = | ||||
|         0xe593d3fdfa8b60e5e17a1b2204662ecbe15c23f2084b9ad5bae40359540a7da9; | ||||
|  | ||||
|     // The type hash for OTC orders, which is: | ||||
|     // keccak256(abi.encodePacked( | ||||
|     //     "OtcOrder(", | ||||
|     //       "address makerToken,", | ||||
|     //       "address takerToken,", | ||||
|     //       "uint128 makerAmount,", | ||||
|     //       "uint128 takerAmount,", | ||||
|     //       "address maker,", | ||||
|     //       "address taker,", | ||||
|     //       "address txOrigin,", | ||||
|     //       "uint256 expiryAndNonce" | ||||
|     //     ")" | ||||
|     // )) | ||||
|     uint256 private constant _OTC_ORDER_TYPEHASH = | ||||
|         0x2f754524de756ae72459efbe1ec88c19a745639821de528ac3fb88f9e65e35c8; | ||||
|  | ||||
|     /// @dev Get the struct hash of a limit order. | ||||
|     /// @param order The limit order. | ||||
|     /// @return structHash The struct hash of the order. | ||||
| @@ -222,6 +256,49 @@ library LibNativeOrder { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the struct hash of an OTC order. | ||||
|     /// @param order The OTC order. | ||||
|     /// @return structHash The struct hash of the order. | ||||
|     function getOtcOrderStructHash(OtcOrder memory order) | ||||
|         internal | ||||
|         pure | ||||
|         returns (bytes32 structHash) | ||||
|     { | ||||
|         // The struct hash is: | ||||
|         // keccak256(abi.encode( | ||||
|         //   TYPE_HASH, | ||||
|         //   order.makerToken, | ||||
|         //   order.takerToken, | ||||
|         //   order.makerAmount, | ||||
|         //   order.takerAmount, | ||||
|         //   order.maker, | ||||
|         //   order.taker, | ||||
|         //   order.txOrigin, | ||||
|         //   order.expiryAndNonce, | ||||
|         // )) | ||||
|         assembly { | ||||
|             let mem := mload(0x40) | ||||
|             mstore(mem, _OTC_ORDER_TYPEHASH) | ||||
|             // order.makerToken; | ||||
|             mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order))) | ||||
|             // order.takerToken; | ||||
|             mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20)))) | ||||
|             // order.makerAmount; | ||||
|             mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40)))) | ||||
|             // order.takerAmount; | ||||
|             mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60)))) | ||||
|             // order.maker; | ||||
|             mstore(add(mem, 0xA0), and(ADDRESS_MASK, mload(add(order, 0x80)))) | ||||
|             // order.taker; | ||||
|             mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0)))) | ||||
|             // order.txOrigin; | ||||
|             mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0)))) | ||||
|             // order.expiryAndNonce; | ||||
|             mstore(add(mem, 0x100), mload(add(order, 0xE0))) | ||||
|             structHash := keccak256(mem, 0x120) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Refund any leftover protocol fees in `msg.value` to `msg.sender`. | ||||
|     /// @param ethProtocolFeePaid How much ETH was paid in protocol fees. | ||||
|     function refundExcessProtocolFeeToSender(uint256 ethProtocolFeePaid) | ||||
|   | ||||
| @@ -404,7 +404,7 @@ abstract contract NativeOrdersSettlement is | ||||
|                 params.order.takerAmount, | ||||
|                 params.order.takerTokenFeeAmount | ||||
|             )); | ||||
|             _transferERC20Tokens( | ||||
|             _transferERC20TokensFrom( | ||||
|                 params.order.takerToken, | ||||
|                 params.taker, | ||||
|                 params.order.feeRecipient, | ||||
| @@ -550,7 +550,7 @@ abstract contract NativeOrdersSettlement is | ||||
|                 settleInfo.takerTokenFilledAmount.safeAdd128(takerTokenFilledAmount); | ||||
|  | ||||
|         // Transfer taker -> maker. | ||||
|         _transferERC20Tokens( | ||||
|         _transferERC20TokensFrom( | ||||
|             settleInfo.takerToken, | ||||
|             settleInfo.taker, | ||||
|             settleInfo.maker, | ||||
| @@ -558,7 +558,7 @@ abstract contract NativeOrdersSettlement is | ||||
|         ); | ||||
|  | ||||
|         // Transfer maker -> taker. | ||||
|         _transferERC20Tokens( | ||||
|         _transferERC20TokensFrom( | ||||
|             settleInfo.makerToken, | ||||
|             settleInfo.maker, | ||||
|             settleInfo.taker, | ||||
|   | ||||
| @@ -35,7 +35,7 @@ abstract contract FixinTokenSpender { | ||||
|     /// @param owner The owner of the tokens. | ||||
|     /// @param to The recipient of the tokens. | ||||
|     /// @param amount The amount of `token` to transfer. | ||||
|     function _transferERC20Tokens( | ||||
|     function _transferERC20TokensFrom( | ||||
|         IERC20TokenV06 token, | ||||
|         address owner, | ||||
|         address to, | ||||
| @@ -87,6 +87,60 @@ abstract contract FixinTokenSpender { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Transfers ERC20 tokens from ourselves to `to`. | ||||
|     /// @param token The token to spend. | ||||
|     /// @param to The recipient of the tokens. | ||||
|     /// @param amount The amount of `token` to transfer. | ||||
|     function _transferERC20Tokens( | ||||
|         IERC20TokenV06 token, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         internal | ||||
|     { | ||||
|         require(address(token) != address(this), "FixinTokenSpender/CANNOT_INVOKE_SELF"); | ||||
|  | ||||
|         assembly { | ||||
|             let ptr := mload(0x40) // free memory pointer | ||||
|  | ||||
|             // selector for transfer(address,uint256) | ||||
|             mstore(ptr, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) | ||||
|             mstore(add(ptr, 0x04), and(to, ADDRESS_MASK)) | ||||
|             mstore(add(ptr, 0x24), amount) | ||||
|  | ||||
|             let success := call( | ||||
|                 gas(), | ||||
|                 and(token, ADDRESS_MASK), | ||||
|                 0, | ||||
|                 ptr, | ||||
|                 0x44, | ||||
|                 ptr, | ||||
|                 32 | ||||
|             ) | ||||
|  | ||||
|             let rdsize := returndatasize() | ||||
|  | ||||
|             // Check for ERC20 success. ERC20 tokens should return a boolean, | ||||
|             // but some don't. We accept 0-length return data as success, or at | ||||
|             // least 32 bytes that starts with a 32-byte boolean true. | ||||
|             success := and( | ||||
|                 success,                             // call itself succeeded | ||||
|                 or( | ||||
|                     iszero(rdsize),                  // no return data, or | ||||
|                     and( | ||||
|                         iszero(lt(rdsize, 32)),      // at least 32 bytes | ||||
|                         eq(mload(ptr), 1)            // starts with uint256(1) | ||||
|                     ) | ||||
|                 ) | ||||
|             ) | ||||
|  | ||||
|             if iszero(success) { | ||||
|                 returndatacopy(ptr, 0, rdsize) | ||||
|                 revert(ptr, rdsize) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Gets the maximum amount of an ERC20 token `token` that can be | ||||
|     ///      pulled from `owner` by this address. | ||||
|     /// @param token The token to spend. | ||||
|   | ||||
| @@ -0,0 +1,45 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 ZeroEx Intl. | ||||
|  | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
|   You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|   Unless required by applicable law or agreed to in writing, software | ||||
|   distributed under the License is distributed on an "AS IS" BASIS, | ||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|   See the License for the specific language governing permissions and | ||||
|   limitations under the License. | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.6.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./LibStorage.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev Storage helpers for `OtcOrdersFeature`. | ||||
| library LibOtcOrdersStorage { | ||||
|  | ||||
|     /// @dev Storage bucket for this feature. | ||||
|     struct Storage { | ||||
|         // tx origin => nonce buckets => min nonce | ||||
|         mapping(address => mapping(uint64 => uint128)) txOriginNonces; | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the storage bucket for this contract. | ||||
|     function getStorage() internal pure returns (Storage storage stor) { | ||||
|         uint256 storageSlot = LibStorage.getStorageSlot( | ||||
|             LibStorage.StorageId.OtcOrders | ||||
|         ); | ||||
|         // 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 } | ||||
|     } | ||||
| } | ||||
| @@ -38,7 +38,8 @@ library LibStorage { | ||||
|         TransformERC20, | ||||
|         MetaTransactions, | ||||
|         ReentrancyGuard, | ||||
|         NativeOrders | ||||
|         NativeOrders, | ||||
|         OtcOrders | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the storage slot given a storage ID. We assign unique, well-spaced | ||||
|   | ||||
| @@ -27,10 +27,12 @@ import "./mixins/MixinBalancerV2.sol"; | ||||
| import "./mixins/MixinBancor.sol"; | ||||
| import "./mixins/MixinCoFiX.sol"; | ||||
| import "./mixins/MixinCurve.sol"; | ||||
| import "./mixins/MixinCurveV2.sol"; | ||||
| import "./mixins/MixinCryptoCom.sol"; | ||||
| import "./mixins/MixinDodo.sol"; | ||||
| import "./mixins/MixinDodoV2.sol"; | ||||
| import "./mixins/MixinKyber.sol"; | ||||
| import "./mixins/MixinKyberDmm.sol"; | ||||
| import "./mixins/MixinMakerPSM.sol"; | ||||
| import "./mixins/MixinMooniswap.sol"; | ||||
| import "./mixins/MixinMStable.sol"; | ||||
| @@ -49,10 +51,12 @@ contract BridgeAdapter is | ||||
|     MixinBancor, | ||||
|     MixinCoFiX, | ||||
|     MixinCurve, | ||||
|     MixinCurveV2, | ||||
|     MixinCryptoCom, | ||||
|     MixinDodo, | ||||
|     MixinDodoV2, | ||||
|     MixinKyber, | ||||
|     MixinKyberDmm, | ||||
|     MixinMakerPSM, | ||||
|     MixinMooniswap, | ||||
|     MixinMStable, | ||||
| @@ -71,6 +75,7 @@ contract BridgeAdapter is | ||||
|         MixinBancor(weth) | ||||
|         MixinCoFiX() | ||||
|         MixinCurve(weth) | ||||
|         MixinCurveV2() | ||||
|         MixinCryptoCom() | ||||
|         MixinDodo() | ||||
|         MixinDodoV2() | ||||
| @@ -105,6 +110,13 @@ contract BridgeAdapter is | ||||
|                 sellAmount, | ||||
|                 order.bridgeData | ||||
|             ); | ||||
|         } else if (protocolId == BridgeProtocols.CURVEV2) { | ||||
|             boughtAmount = _tradeCurveV2( | ||||
|                 sellToken, | ||||
|                 buyToken, | ||||
|                 sellAmount, | ||||
|                 order.bridgeData | ||||
|             ); | ||||
|         } else if (protocolId == BridgeProtocols.UNISWAPV3) { | ||||
|             boughtAmount = _tradeUniswapV3( | ||||
|                 sellToken, | ||||
| @@ -217,6 +229,12 @@ contract BridgeAdapter is | ||||
|                 sellAmount, | ||||
|                 order.bridgeData | ||||
|             ); | ||||
|         } else if (protocolId == BridgeProtocols.KYBERDMM) { | ||||
|             boughtAmount = _tradeKyberDmm( | ||||
|                 buyToken, | ||||
|                 sellAmount, | ||||
|                 order.bridgeData | ||||
|             ); | ||||
|         } else { | ||||
|             boughtAmount = _tradeZeroExBridge( | ||||
|                 sellToken, | ||||
|   | ||||
| @@ -46,4 +46,6 @@ library BridgeProtocols { | ||||
|     uint128 internal constant MAKERPSM    = 16; | ||||
|     uint128 internal constant BALANCERV2  = 17; | ||||
|     uint128 internal constant UNISWAPV3   = 18; | ||||
|     uint128 internal constant KYBERDMM    = 19; | ||||
|     uint128 internal constant CURVEV2     = 20; | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,71 @@ | ||||
| // 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/errors/LibRichErrorsV06.sol"; | ||||
| 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"; | ||||
|  | ||||
| contract MixinCurveV2 { | ||||
|  | ||||
|     using LibERC20TokenV06 for IERC20TokenV06; | ||||
|     using LibSafeMathV06 for uint256; | ||||
|     using LibRichErrorsV06 for bytes; | ||||
|  | ||||
|     struct CurveBridgeDataV2 { | ||||
|         address curveAddress; | ||||
|         bytes4 exchangeFunctionSelector; | ||||
|         int128 fromCoinIdx; | ||||
|         int128 toCoinIdx; | ||||
|     } | ||||
|  | ||||
|     function _tradeCurveV2( | ||||
|         IERC20TokenV06 sellToken, | ||||
|         IERC20TokenV06 buyToken, | ||||
|         uint256 sellAmount, | ||||
|         bytes memory bridgeData | ||||
|     ) | ||||
|         internal | ||||
|         returns (uint256 boughtAmount) | ||||
|     { | ||||
|         // Decode the bridge data to get the Curve metadata. | ||||
|         CurveBridgeDataV2 memory data = abi.decode(bridgeData, (CurveBridgeDataV2)); | ||||
|         sellToken.approveIfBelow(data.curveAddress, sellAmount); | ||||
|  | ||||
|         uint256 beforeBalance = buyToken.balanceOf(address(this)); | ||||
|         (bool success, bytes memory resultData) = | ||||
|             data.curveAddress.call(abi.encodeWithSelector( | ||||
|                 data.exchangeFunctionSelector, | ||||
|                 data.fromCoinIdx, | ||||
|                 data.toCoinIdx, | ||||
|                 // dx | ||||
|                 sellAmount, | ||||
|                 // min dy | ||||
|                 1 | ||||
|             )); | ||||
|         if (!success) { | ||||
|             resultData.rrevert(); | ||||
|         } | ||||
|  | ||||
|         return buyToken.balanceOf(address(this)).safeSub(beforeBalance); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,94 @@ | ||||
| // 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/LibERC20TokenV06.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "../IBridgeAdapter.sol"; | ||||
|  | ||||
| /* | ||||
|     KyberDmm Router | ||||
| */ | ||||
| interface IKyberDmmRouter { | ||||
|  | ||||
|     /// @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 amountIn The amount of input tokens to send. | ||||
|     /// @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert. | ||||
|     /// @param pools An array of pool addresses. pools.length must be >= 1. | ||||
|     /// @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 to Recipient of the output tokens. | ||||
|     /// @param deadline Unix timestamp after which the transaction will revert. | ||||
|     /// @return amounts The input token amount and all subsequent output token amounts. | ||||
|     function swapExactTokensForTokens( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address[] calldata pools, | ||||
|         address[] calldata path, | ||||
|         address to, | ||||
|         uint deadline | ||||
|     ) external returns (uint[] memory amounts); | ||||
| } | ||||
|  | ||||
| contract MixinKyberDmm { | ||||
|  | ||||
|     using LibERC20TokenV06 for IERC20TokenV06; | ||||
|  | ||||
|     function _tradeKyberDmm( | ||||
|         IERC20TokenV06 buyToken, | ||||
|         uint256 sellAmount, | ||||
|         bytes memory bridgeData | ||||
|     ) | ||||
|         internal | ||||
|         returns (uint256 boughtAmount) | ||||
|     { | ||||
|         address router; | ||||
|         address[] memory pools; | ||||
|         address[] memory path; | ||||
|         (router, pools, path) = abi.decode(bridgeData, (address, address[], address[])); | ||||
|  | ||||
|         require(pools.length >= 1, "MixinKyberDmm/POOLS_LENGTH_MUST_BE_AT_LEAST_ONE"); | ||||
|         require(path.length == pools.length + 1, "MixinKyberDmm/ARRAY_LENGTH_MISMATCH"); | ||||
|          require( | ||||
|              path[path.length - 1] == address(buyToken), | ||||
|              "MixinKyberDmm/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN" | ||||
|          ); | ||||
|         // Grant the KyberDmm router an allowance to sell the first token. | ||||
|         IERC20TokenV06(path[0]).approveIfBelow(address(router), sellAmount); | ||||
|  | ||||
|         uint[] memory amounts = IKyberDmmRouter(router).swapExactTokensForTokens( | ||||
|              // Sell all tokens we hold. | ||||
|             sellAmount, | ||||
|              // Minimum buy amount. | ||||
|             1, | ||||
|             pools, | ||||
|             // Convert to `buyToken` along this path. | ||||
|             path, | ||||
|             // Recipient is `this`. | ||||
|             address(this), | ||||
|             // Expires after this block. | ||||
|             block.timestamp | ||||
|         ); | ||||
|         return amounts[amounts.length-1]; | ||||
|     } | ||||
| } | ||||
| @@ -31,6 +31,7 @@ interface IMStable { | ||||
|         IERC20TokenV06 sellToken, | ||||
|         IERC20TokenV06 buyToken, | ||||
|         uint256 sellAmount, | ||||
|         uint256 minBoughtAmount, | ||||
|         address recipient | ||||
|     ) | ||||
|         external | ||||
| @@ -59,6 +60,8 @@ contract MixinMStable { | ||||
|             sellToken, | ||||
|             buyToken, | ||||
|             sellAmount, | ||||
|             // Minimum buy amount. | ||||
|             1, | ||||
|             address(this) | ||||
|         ); | ||||
|     } | ||||
|   | ||||
| @@ -69,7 +69,7 @@ contract MixinUniswapV2 { | ||||
|             assembly { path := _path } | ||||
|         } | ||||
|  | ||||
|         require(path.length >= 2, "MixinUniswapV3/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||
|         require(path.length >= 2, "MixinUniswapV2/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||
|         require( | ||||
|             path[path.length - 1] == buyToken, | ||||
|             "MixinUniswapV2/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN" | ||||
|   | ||||
							
								
								
									
										44
									
								
								contracts/zero-ex/contracts/src/vendor/IUniswapV3Pool.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								contracts/zero-ex/contracts/src/vendor/IUniswapV3Pool.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.12; | ||||
|  | ||||
|  | ||||
| interface IUniswapV3Pool { | ||||
|  | ||||
|     /// @notice Swap token0 for token1, or token1 for token0 | ||||
|     /// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback | ||||
|     /// @param recipient The address to receive the output of the swap | ||||
|     /// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0 | ||||
|     /// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) | ||||
|     /// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this | ||||
|     /// value after the swap. If one for zero, the price cannot be greater than this value after the swap | ||||
|     /// @param data Any data to be passed through to the callback | ||||
|     /// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive | ||||
|     /// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive | ||||
|     function swap( | ||||
|         address recipient, | ||||
|         bool zeroForOne, | ||||
|         int256 amountSpecified, | ||||
|         uint160 sqrtPriceLimitX96, | ||||
|         bytes calldata data | ||||
|     ) | ||||
|         external | ||||
|         returns (int256 amount0, int256 amount1); | ||||
| } | ||||
| @@ -28,7 +28,7 @@ contract TestFixinTokenSpender is | ||||
| { | ||||
|     constructor() public {} | ||||
|  | ||||
|     function transferERC20Tokens( | ||||
|     function transferERC20TokensFrom( | ||||
|         IERC20TokenV06 token, | ||||
|         address owner, | ||||
|         address to, | ||||
| @@ -36,7 +36,7 @@ contract TestFixinTokenSpender is | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         _transferERC20Tokens( | ||||
|         _transferERC20TokensFrom( | ||||
|             token, | ||||
|             owner, | ||||
|             to, | ||||
|   | ||||
							
								
								
									
										4
									
								
								contracts/zero-ex/contracts/test/TestNoEthRecipient.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								contracts/zero-ex/contracts/test/TestNoEthRecipient.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| pragma solidity ^0.6; | ||||
|  | ||||
| contract TestNoEthRecipient {} | ||||
							
								
								
									
										46
									
								
								contracts/zero-ex/contracts/test/TestUniswapV3Factory.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								contracts/zero-ex/contracts/test/TestUniswapV3Factory.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| pragma solidity ^0.6; | ||||
| pragma experimental ABIEncoderV2; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "./TestUniswapV3Pool.sol"; | ||||
|  | ||||
| contract TestUniswapV3Factory { | ||||
|     struct CreationParameters { | ||||
|         IERC20TokenV06 token0; | ||||
|         IERC20TokenV06 token1; | ||||
|         uint24 fee; | ||||
|     } | ||||
|  | ||||
|     event PoolCreated(TestUniswapV3Pool pool); | ||||
|  | ||||
|     bytes32 public immutable POOL_INIT_CODE_HASH; | ||||
|     mapping (IERC20TokenV06 => mapping (IERC20TokenV06 => mapping (uint24 => TestUniswapV3Pool))) public getPool; | ||||
|     CreationParameters public creationParameters; | ||||
|  | ||||
|     constructor() public { | ||||
|         POOL_INIT_CODE_HASH = keccak256(type(TestUniswapV3Pool).creationCode); | ||||
|     } | ||||
|  | ||||
|     function createPool(IERC20TokenV06 tokenA, IERC20TokenV06 tokenB, uint24 fee) | ||||
|         external | ||||
|         returns (TestUniswapV3Pool pool) | ||||
|     { | ||||
|         (IERC20TokenV06 token0, IERC20TokenV06 token1) = tokenA < tokenB | ||||
|             ? (tokenA, tokenB) | ||||
|             : (tokenB, tokenA); | ||||
|         require( | ||||
|             getPool[token0][token1][fee] == TestUniswapV3Pool(0), | ||||
|             "TestUniswapV3Factory/POOL_ALREADY_EXISTS" | ||||
|         ); | ||||
|         creationParameters = CreationParameters({ | ||||
|             token0: token0, | ||||
|             token1: token1, | ||||
|             fee: fee | ||||
|         }); | ||||
|         pool = new TestUniswapV3Pool | ||||
|             { salt: keccak256(abi.encode(token0, token1, fee)) }(); | ||||
|         getPool[token0][token1][fee] = pool; | ||||
|         getPool[token1][token0][fee] = pool; | ||||
|         emit PoolCreated(pool); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										17
									
								
								contracts/zero-ex/contracts/test/TestUniswapV3Feature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								contracts/zero-ex/contracts/test/TestUniswapV3Feature.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| pragma solidity ^0.6; | ||||
| pragma experimental ABIEncoderV2; | ||||
| import "../src/features/UniswapV3Feature.sol"; | ||||
|  | ||||
| contract TestUniswapV3Feature is UniswapV3Feature { | ||||
|     constructor( | ||||
|         IEtherTokenV06 weth, | ||||
|         address uniFactory, | ||||
|         bytes32 poolInitCodeHash | ||||
|     ) | ||||
|         UniswapV3Feature(weth, uniFactory, poolInitCodeHash) | ||||
|         public | ||||
|     {} | ||||
|  | ||||
|     receive() external payable {} | ||||
| } | ||||
							
								
								
									
										75
									
								
								contracts/zero-ex/contracts/test/TestUniswapV3Pool.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								contracts/zero-ex/contracts/test/TestUniswapV3Pool.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| pragma solidity ^0.6; | ||||
| pragma experimental ABIEncoderV2; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "../src/vendor/IUniswapV3Pool.sol"; | ||||
|  | ||||
| interface IUniswapV3PoolDeployer { | ||||
|     struct CreationParameters { | ||||
|         IERC20TokenV06 token0; | ||||
|         IERC20TokenV06 token1; | ||||
|         uint24 fee; | ||||
|     } | ||||
|  | ||||
|     function creationParameters() external view returns (CreationParameters memory); | ||||
| } | ||||
|  | ||||
| interface IUniswapV3SwapCallback { | ||||
|     function uniswapV3SwapCallback( | ||||
|         int256 amount0Delta, | ||||
|         int256 amount1Delta, | ||||
|         bytes calldata data | ||||
|     ) | ||||
|         external; | ||||
| } | ||||
|  | ||||
| contract TestUniswapV3Pool is IUniswapV3Pool { | ||||
|     IERC20TokenV06 public immutable token0; | ||||
|     IERC20TokenV06 public immutable token1; | ||||
|     uint24 public immutable fee; | ||||
|  | ||||
|     constructor() public { | ||||
|         IUniswapV3PoolDeployer.CreationParameters memory params = | ||||
|             IUniswapV3PoolDeployer(msg.sender).creationParameters(); | ||||
|         (token0, token1, fee) = (params.token0, params.token1, params.fee); | ||||
|     } | ||||
|  | ||||
|     function swap( | ||||
|         address recipient, | ||||
|         bool zeroForOne, | ||||
|         int256 amountSpecified, | ||||
|         uint160, | ||||
|         bytes calldata data | ||||
|     ) | ||||
|         external | ||||
|         override | ||||
|         returns (int256 amount0, int256 amount1) | ||||
|     { | ||||
|         uint256 balance0Before = token0.balanceOf(address(this)); | ||||
|         uint256 balance1Before = token1.balanceOf(address(this)); | ||||
|         if (zeroForOne) { | ||||
|             amount0 = int256(amountSpecified); | ||||
|             // Always buy 100% of other token balance. | ||||
|             amount1 = -int256(balance1Before); | ||||
|             token1.transfer(recipient, balance1Before); | ||||
|         } else { | ||||
|             amount0 = -int256(balance0Before); | ||||
|             // Always buy 100% of other token balance. | ||||
|             amount1 = int256(amountSpecified); | ||||
|             token0.transfer(recipient, balance0Before); | ||||
|         } | ||||
|         IUniswapV3SwapCallback(msg.sender).uniswapV3SwapCallback( | ||||
|             amount0, | ||||
|             amount1, | ||||
|             data | ||||
|         ); | ||||
|         int256 balance0Change = int256(token0.balanceOf(address(this))) - | ||||
|             int256(balance0Before); | ||||
|         int256 balance1Change = int256(token1.balanceOf(address(this))) - | ||||
|             int256(balance1Before); | ||||
|         require( | ||||
|             balance0Change >= amount0 && balance1Change >= amount1, | ||||
|             "TestUniswapV3Pool/SWAP_NOT_PAID" | ||||
|         ); | ||||
|     } | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user