Compare commits
	
		
			30 Commits
		
	
	
		
			@0x/protoc
			...
			protocol@7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 7a59b7eafe | ||
|  | 9e59d41e44 | ||
|  | 475e6c7bca | ||
|  | dbc5a5293e | ||
|  | f4bd2bd0d8 | ||
|  | f1782a83ba | ||
|  | cbade0d558 | ||
|  | fe0c26387c | ||
|  | c03a014740 | ||
|  | 84e6d788aa | ||
|  | cd296b8767 | ||
|  | 5946d32a7d | ||
|  | 842dd8572b | ||
|  | 33e260f9db | ||
|  | c44f8d0060 | ||
|  | 411548a33e | ||
|  | 9a17ce1383 | ||
|  | 2b120d0669 | ||
|  | 6d877d5242 | ||
|  | e4abd690e7 | ||
|  | 2a194384b6 | ||
|  | 1e069e6f8a | ||
|  | a019bb913d | ||
|  | 9ce73931f7 | ||
|  | 97020df178 | ||
|  | dfb7b3de8f | ||
|  | 9e152912fe | ||
|  | b2c2f1e1aa | ||
|  | 629c7d8e92 | ||
|  | 62f24d4356 | 
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "3.7.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "3.7.9", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.7.10 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.7.9 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-asset-proxy", | ||||
|     "version": "3.7.9", | ||||
|     "version": "3.7.10", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -51,15 +51,15 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contract-wrappers": "^13.15.0", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contract-wrappers": "^13.16.0", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -67,7 +67,7 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
| @@ -79,17 +79,17 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-erc1155": "^2.1.27", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-erc721": "^3.1.27", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-erc1155": "^2.1.28", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-erc721": "^3.1.28", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -168,7 +168,7 @@ describe('StaticCallProxy', () => { | ||||
|         it('should revert if the hash of the output is different than expected expected', async () => { | ||||
|             const staticCallData = staticCallTarget.isOddNumber(new BigNumber(0)).getABIEncodedTransactionData(); | ||||
|             const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.keccak256(trueAsBuffer)); | ||||
|             const assetData = assetDataInterface | ||||
|                 .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash) | ||||
|                 .getABIEncodedTransactionData(); | ||||
| @@ -199,7 +199,7 @@ describe('StaticCallProxy', () => { | ||||
|         it('should be successful if a function call with one static input returns the correct value', async () => { | ||||
|             const staticCallData = staticCallTarget.isOddNumber(new BigNumber(1)).getABIEncodedTransactionData(); | ||||
|             const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); | ||||
|             const expectedResultHash = ethUtil.bufferToHex(ethUtil.keccak256(trueAsBuffer)); | ||||
|             const assetData = assetDataInterface | ||||
|                 .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash) | ||||
|                 .getABIEncodedTransactionData(); | ||||
| @@ -232,7 +232,7 @@ describe('StaticCallProxy', () => { | ||||
|             const offset = '0000000000000000000000000000000000000000000000000000000000000020'; | ||||
|             const encodedExpectedResultWithOffset = `0x${offset}${abiEncoder.encode(expectedResults).slice(2)}`; | ||||
|             const expectedResultHash = ethUtil.bufferToHex( | ||||
|                 ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)), | ||||
|                 ethUtil.keccak256(ethUtil.toBuffer(encodedExpectedResultWithOffset)), | ||||
|             ); | ||||
|             const assetData = assetDataInterface | ||||
|                 .StaticCall(staticCallTarget.address, staticCallData, expectedResultHash) | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "1.1.28", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "1.1.27", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.1.28 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.27 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-broker", | ||||
|     "version": "1.1.27", | ||||
|     "version": "1.1.28", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -51,20 +51,20 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-erc721": "^3.1.27", | ||||
|         "@0x/contracts-exchange": "^3.2.28", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-erc721": "^3.1.28", | ||||
|         "@0x/contracts-exchange": "^3.2.29", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -84,11 +84,11 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "3.1.29", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "3.1.28", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.1.29 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.28 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-coordinator", | ||||
|     "version": "3.1.28", | ||||
|     "version": "3.1.29", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,17 +52,17 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-dev-utils": "^1.3.26", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-dev-utils": "^1.3.27", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -82,17 +82,17 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.21", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/assert": "^3.0.26", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contract-addresses": "^6.0.0", | ||||
|         "@0x/contracts-exchange": "^3.2.28", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/json-schemas": "^5.4.1", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "@0x/contracts-exchange": "^3.2.29", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/json-schemas": "^6.1.2", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "http-status-codes": "^1.3.2" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -1,8 +1,4 @@ | ||||
| import { assert as sharedAssert } from '@0x/assert'; | ||||
| // HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here | ||||
| import { Schema } from '@0x/json-schemas'; // tslint:disable-line:no-unused-variable | ||||
| import { Order } from '@0x/types'; // tslint:disable-line:no-unused-variable | ||||
| import { BigNumber } from '@0x/utils'; // tslint:disable-line:no-unused-variable | ||||
| import { Web3Wrapper } from '@0x/web3-wrapper'; | ||||
|  | ||||
| export const assert = { | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "1.3.27", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "1.3.26", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.3.27 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.3.26 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-dev-utils", | ||||
|     "version": "1.3.26", | ||||
|     "version": "1.3.27", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -41,18 +41,18 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/assert": "^3.0.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/assert": "^3.0.26", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethers": "~4.0.4", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
| @@ -63,7 +63,7 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@types/node": "12.12.54" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "2.1.28", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "2.1.27", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.1.28 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.1.27 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc1155", | ||||
|     "version": "2.1.27", | ||||
|     "version": "2.1.28", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,15 +52,15 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -68,7 +68,7 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
|         "npm-run-all": "^4.1.2", | ||||
| @@ -80,10 +80,10 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "3.3.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "3.3.6", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.3.7 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.6 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc20", | ||||
|     "version": "3.3.6", | ||||
|     "version": "3.3.7", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -51,18 +51,18 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -70,7 +70,7 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -82,7 +82,7 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18" | ||||
|         "@0x/base-contract": "^6.3.2" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "3.1.28", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "3.1.27", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.1.28 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.1.27 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc721", | ||||
|     "version": "3.1.27", | ||||
|     "version": "3.1.28", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,18 +52,18 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -71,7 +71,7 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -84,7 +84,7 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18" | ||||
|         "@0x/base-contract": "^6.3.2" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "4.2.29", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "4.2.28", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.2.29 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.2.28 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange-forwarder", | ||||
|     "version": "4.2.28", | ||||
|     "version": "4.2.29", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,25 +52,25 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-dev-utils": "^1.3.26", | ||||
|         "@0x/contracts-erc1155": "^2.1.27", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-erc721": "^3.1.27", | ||||
|         "@0x/contracts-exchange": "^3.2.28", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-dev-utils": "^1.3.27", | ||||
|         "@0x/contracts-erc1155": "^2.1.28", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-erc721": "^3.1.28", | ||||
|         "@0x/contracts-exchange": "^3.2.29", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -90,9 +90,9 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "4.3.28", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "4.3.27", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.3.28 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.3.27 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange-libs", | ||||
|     "version": "4.3.27", | ||||
|     "version": "4.3.28", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,14 +52,14 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/subproviders": "^6.4.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/subproviders": "^6.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -67,7 +67,7 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -80,14 +80,14 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "3.2.29", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "3.2.28", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.2.29 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.2.28 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-exchange", | ||||
|     "version": "3.2.28", | ||||
|     "version": "3.2.29", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,21 +52,21 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-multisig": "^4.1.28", | ||||
|         "@0x/contracts-staking": "^2.0.35", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-multisig": "^4.1.29", | ||||
|         "@0x/contracts-staking": "^2.0.36", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -74,8 +74,8 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "js-combinatorics": "^0.5.3", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -88,13 +88,13 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-dev-utils": "^1.3.26", | ||||
|         "@0x/contracts-erc1155": "^2.1.27", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-erc721": "^3.1.27", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-dev-utils": "^1.3.27", | ||||
|         "@0x/contracts-erc1155": "^2.1.28", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-erc721": "^3.1.28", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -86,7 +86,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { | ||||
|  | ||||
|     const SIGNATURE_LENGTH = 65; | ||||
|     const generateRandomSignature = (): string => hexUtils.random(SIGNATURE_LENGTH); | ||||
|     const hashBytes = (bytesHex: string): string => ethUtil.bufferToHex(ethUtil.sha3(ethUtil.toBuffer(bytesHex))); | ||||
|     const hashBytes = (bytesHex: string): string => hexUtils.hash(bytesHex); | ||||
|     const signDataHex = (dataHex: string, privateKey: Buffer): string => { | ||||
|         const ecSignature = ethUtil.ecsign(ethUtil.toBuffer(dataHex), privateKey); | ||||
|         return hexUtils.concat(ecSignature.v, ecSignature.r, ecSignature.s); | ||||
|   | ||||
| @@ -12,7 +12,6 @@ import { ReferenceFunctions as UtilReferenceFunctions, SafeMathRevertErrors } fr | ||||
| import { FillResults, Order } from '@0x/types'; | ||||
| import { AnyRevertError, BigNumber, ExchangeRevertErrors, hexUtils, StringRevertError } from '@0x/utils'; | ||||
| import { LogEntry, LogWithDecodedArgs } from 'ethereum-types'; | ||||
| import * as ethjs from 'ethereumjs-util'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
| @@ -104,7 +103,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => { | ||||
|     // Creates a deterministic order signature, even though no signature validation | ||||
|     // actually occurs in the test contract. | ||||
|     function createOrderSignature(order: Order): string { | ||||
|         return ethjs.bufferToHex(ethjs.sha3(ethjs.toBuffer(orderHashUtils.getOrderHashHex(order)))); | ||||
|         return hexUtils.hash(orderHashUtils.getOrderHashHex(order)); | ||||
|     } | ||||
|  | ||||
|     // Asserts that `_fillOrder()` was called in the same order and with the same | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "6.2.23", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "6.2.22", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v6.2.23 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v6.2.22 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-extensions", | ||||
|     "version": "6.2.22", | ||||
|     "version": "6.2.23", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,23 +52,23 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-dev-utils": "^1.3.26", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-erc721": "^3.1.27", | ||||
|         "@0x/contracts-exchange": "^3.2.28", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-dev-utils": "^1.3.27", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-erc721": "^3.1.28", | ||||
|         "@0x/contracts-exchange": "^3.2.29", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -77,7 +77,7 @@ | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereumjs-abi": "0.6.5", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -90,10 +90,10 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-integrations", | ||||
|     "version": "2.7.32", | ||||
|     "version": "2.7.39", | ||||
|     "private": true, | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
| @@ -52,25 +52,25 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contract-addresses": "^6.0.0", | ||||
|         "@0x/contract-wrappers": "^13.15.0", | ||||
|         "@0x/contracts-broker": "^1.1.27", | ||||
|         "@0x/contracts-coordinator": "^3.1.28", | ||||
|         "@0x/contracts-dev-utils": "^1.3.26", | ||||
|         "@0x/contracts-exchange-forwarder": "^4.2.28", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-extensions": "^6.2.22", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/contract-wrappers": "^13.16.0", | ||||
|         "@0x/contracts-broker": "^1.1.28", | ||||
|         "@0x/contracts-coordinator": "^3.1.29", | ||||
|         "@0x/contracts-dev-utils": "^1.3.27", | ||||
|         "@0x/contracts-exchange-forwarder": "^4.2.29", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-extensions": "^6.2.23", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/coordinator-server": "^1.0.5", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/migrations": "^8.0.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/protocol-utils": "^1.4.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/migrations": "^8.0.5", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/protocol-utils": "^1.5.1", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@azure/core-asynciterator-polyfill": "^1.0.0", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
| @@ -93,23 +93,23 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/asset-swapper": "^6.5.1", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-erc1155": "^2.1.27", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-erc721": "^3.1.27", | ||||
|         "@0x/contracts-exchange": "^3.2.28", | ||||
|         "@0x/contracts-multisig": "^4.1.28", | ||||
|         "@0x/contracts-staking": "^2.0.35", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-zero-ex": "^0.21.1", | ||||
|         "@0x/subproviders": "^6.4.1", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^6.2.0", | ||||
|         "@0x/asset-swapper": "^6.9.1", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-erc1155": "^2.1.28", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-erc721": "^3.1.28", | ||||
|         "@0x/contracts-exchange": "^3.2.29", | ||||
|         "@0x/contracts-multisig": "^4.1.29", | ||||
|         "@0x/contracts-staking": "^2.0.36", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-zero-ex": "^0.22.3", | ||||
|         "@0x/subproviders": "^6.5.2", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "4.1.29", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "4.1.28", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.1.29 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.1.28 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-multisig", | ||||
|     "version": "4.1.28", | ||||
|     "version": "4.1.29", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -49,18 +49,18 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
| @@ -78,9 +78,9 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "2.0.36", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "2.0.35", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v2.0.36 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v2.0.35 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-staking", | ||||
|     "version": "2.0.35", | ||||
|     "version": "2.0.36", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,20 +53,20 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-dev-utils": "^1.3.26", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-dev-utils": "^1.3.27", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/node": "12.12.54", | ||||
|         "chai": "^4.0.1", | ||||
| @@ -87,12 +87,12 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^5.1.1" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "5.3.25", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "5.3.24", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v5.3.25 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v5.3.24 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-test-utils", | ||||
|     "version": "5.3.24", | ||||
|     "version": "5.3.25", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -34,28 +34,28 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils", | ||||
|     "devDependencies": { | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "npm-run-all": "^4.1.2", | ||||
|         "shx": "^0.2.2", | ||||
|         "tslint": "5.11.0", | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.21", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/assert": "^3.0.26", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/contract-addresses": "^6.0.0", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/json-schemas": "^5.4.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-coverage": "^4.0.31", | ||||
|         "@0x/sol-profiler": "^4.1.21", | ||||
|         "@0x/sol-trace": "^3.0.31", | ||||
|         "@0x/subproviders": "^6.4.1", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/json-schemas": "^6.1.2", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-coverage": "^4.0.36", | ||||
|         "@0x/sol-profiler": "^4.1.26", | ||||
|         "@0x/sol-trace": "^3.0.36", | ||||
|         "@0x/subproviders": "^6.5.2", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/bn.js": "^4.11.0", | ||||
|         "@types/js-combinatorics": "^0.5.29", | ||||
|         "@types/lodash": "4.14.104", | ||||
| @@ -67,8 +67,8 @@ | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "decimal.js": "^10.2.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "ethers": "~4.0.4", | ||||
|         "js-combinatorics": "^0.5.3", | ||||
|         "lodash": "^4.17.11", | ||||
|   | ||||
| @@ -77,7 +77,7 @@ export const constants = { | ||||
|     ZERO_AMOUNT: new BigNumber(0), | ||||
|     PERCENTAGE_DENOMINATOR: new BigNumber(10).pow(18), | ||||
|     TIME_BUFFER: new BigNumber(1000), | ||||
|     KECCAK256_NULL: ethUtil.addHexPrefix(ethUtil.bufferToHex(ethUtil.SHA3_NULL)), | ||||
|     KECCAK256_NULL: ethUtil.bufferToHex(ethUtil.keccak256(Buffer.alloc(0))), | ||||
|     MAX_UINT256_ROOT: new BigNumber('340282366920938463463374607431768211456'), | ||||
|     ONE_ETHER: new BigNumber(1e18), | ||||
|     EIP712_DOMAIN_NAME: '0x Protocol', | ||||
|   | ||||
| @@ -57,9 +57,7 @@ describe('Order hashing', () => { | ||||
|                 ...order, | ||||
|                 takerAddress: (null as any) as string, | ||||
|             }; | ||||
|             const expectedErrorMessage = `Order taker must be of type string. If you want anyone to be able to fill an order - pass ${ | ||||
|                 constants.NULL_ADDRESS | ||||
|             }`; | ||||
|             const expectedErrorMessage = `Expected order to conform to schema`; | ||||
|             expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage); | ||||
|         }); | ||||
|     }); | ||||
|   | ||||
| @@ -1,4 +1,32 @@ | ||||
| [ | ||||
|     { | ||||
|         "version": "1.1.5", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Patched votingPower logic", | ||||
|                 "pr": 214 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619825976 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "1.1.4", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1619481586, | ||||
|         "version": "1.1.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1618259868, | ||||
|         "version": "1.1.2", | ||||
|   | ||||
| @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.1.5 - _April 30, 2021_ | ||||
|  | ||||
|     * Patched votingPower logic (#214) | ||||
|  | ||||
| ## v1.1.4 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.3 - _April 26, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.1.2 - _April 12, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -30,6 +30,7 @@ interface IZrxTreasury { | ||||
|         uint256 votingPeriod; | ||||
|         uint256 proposalThreshold; | ||||
|         uint256 quorumThreshold; | ||||
|         bytes32 defaultPoolId; | ||||
|     } | ||||
|  | ||||
|     struct ProposedAction { | ||||
|   | ||||
| @@ -20,8 +20,6 @@ | ||||
| pragma solidity ^0.6.12; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol"; | ||||
| @@ -32,7 +30,6 @@ import "./IZrxTreasury.sol"; | ||||
| contract ZrxTreasury is | ||||
|     IZrxTreasury | ||||
| { | ||||
|     using LibERC20TokenV06 for IERC20TokenV06; | ||||
|     using LibSafeMathV06 for uint256; | ||||
|     using LibRichErrorsV06 for bytes; | ||||
|     using LibBytesV06 for bytes; | ||||
| @@ -52,11 +49,9 @@ contract ZrxTreasury is | ||||
|     /// @dev Initializes the ZRX treasury and creates the default | ||||
|     ///      staking pool. | ||||
|     /// @param stakingProxy_ The 0x staking proxy contract. | ||||
|     /// @param weth_ The WETH token contract. | ||||
|     /// @param params Immutable treasury parameters. | ||||
|     constructor( | ||||
|         IStaking stakingProxy_, | ||||
|         IERC20TokenV06 weth_, | ||||
|         TreasuryParameters memory params | ||||
|     ) | ||||
|         public | ||||
| @@ -66,15 +61,12 @@ contract ZrxTreasury is | ||||
|             "VOTING_PERIOD_TOO_LONG" | ||||
|         ); | ||||
|         stakingProxy = stakingProxy_; | ||||
|         DefaultPoolOperator defaultPoolOperator_ = new DefaultPoolOperator( | ||||
|             stakingProxy_, | ||||
|             weth_ | ||||
|         ); | ||||
|         defaultPoolOperator = defaultPoolOperator_; | ||||
|         defaultPoolId = defaultPoolOperator_.poolId(); | ||||
|         votingPeriod = params.votingPeriod; | ||||
|         proposalThreshold = params.proposalThreshold; | ||||
|         quorumThreshold = params.quorumThreshold; | ||||
|         defaultPoolId = params.defaultPoolId; | ||||
|         IStaking.Pool memory defaultPool = stakingProxy_.getStakingPool(params.defaultPoolId); | ||||
|         defaultPoolOperator = DefaultPoolOperator(defaultPool.operator); | ||||
|     } | ||||
|  | ||||
|     // solhint-disable | ||||
| @@ -286,6 +278,12 @@ contract ZrxTreasury is | ||||
|  | ||||
|         // Add voting power for operated staking pools. | ||||
|         for (uint256 i = 0; i != operatedPoolIds.length; i++) { | ||||
|             for (uint256 j = 0; j != i; j++) { | ||||
|                 require( | ||||
|                     operatedPoolIds[i] != operatedPoolIds[j], | ||||
|                     "getVotingPower/DUPLICATE_POOL_ID" | ||||
|                 ); | ||||
|             } | ||||
|             IStaking.Pool memory pool = stakingProxy.getStakingPool(operatedPoolIds[i]); | ||||
|             require( | ||||
|                 pool.operator == account, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-treasury", | ||||
|     "version": "1.1.2", | ||||
|     "version": "1.1.5", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -46,16 +46,16 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contract-addresses": "^6.0.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-staking": "^2.0.35", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-staking": "^2.0.36", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@types/isomorphic-fetch": "^0.0.35", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
| @@ -72,15 +72,15 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/protocol-utils": "^1.4.1", | ||||
|         "@0x/subproviders": "^6.4.1", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^5.1.1" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/protocol-utils": "^1.5.1", | ||||
|         "@0x/subproviders": "^6.5.2", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -28,6 +28,7 @@ blockchainTests.resets('Treasury governance', env => { | ||||
|         votingPeriod: new BigNumber(3).times(stakingConstants.ONE_DAY_IN_SECONDS), | ||||
|         proposalThreshold: new BigNumber(100), | ||||
|         quorumThreshold: new BigNumber(1000), | ||||
|         defaultPoolId: stakingConstants.INITIAL_POOL_ID, | ||||
|     }; | ||||
|     const PROPOSAL_DESCRIPTION = 'A very compelling proposal!'; | ||||
|     const TREASURY_BALANCE = constants.INITIAL_ERC20_BALANCE; | ||||
| @@ -135,6 +136,16 @@ blockchainTests.resets('Treasury governance', env => { | ||||
|             .approve(erc20ProxyContract.address, constants.INITIAL_ERC20_ALLOWANCE) | ||||
|             .awaitTransactionSuccessAsync({ from: delegator }); | ||||
|  | ||||
|         defaultPoolOperator = await DefaultPoolOperatorContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.DefaultPoolOperator, | ||||
|             env.provider, | ||||
|             env.txDefaults, | ||||
|             { ...artifacts, ...erc20Artifacts }, | ||||
|             staking.address, | ||||
|             weth.address, | ||||
|         ); | ||||
|         defaultPoolId = stakingConstants.INITIAL_POOL_ID; | ||||
|  | ||||
|         const createStakingPoolTx = staking.createStakingPool(stakingConstants.PPM, false); | ||||
|         nonDefaultPoolId = await createStakingPoolTx.callAsync({ from: poolOperator }); | ||||
|         await createStakingPoolTx.awaitTransactionSuccessAsync({ from: poolOperator }); | ||||
| @@ -145,9 +156,9 @@ blockchainTests.resets('Treasury governance', env => { | ||||
|             env.txDefaults, | ||||
|             { ...artifacts, ...erc20Artifacts }, | ||||
|             staking.address, | ||||
|             weth.address, | ||||
|             TREASURY_PARAMS, | ||||
|         ); | ||||
|  | ||||
|         await zrx.mint(TREASURY_BALANCE).awaitTransactionSuccessAsync(); | ||||
|         await zrx.transfer(treasury.address, TREASURY_BALANCE).awaitTransactionSuccessAsync(); | ||||
|         actions = [ | ||||
| @@ -166,10 +177,6 @@ blockchainTests.resets('Treasury governance', env => { | ||||
|                 value: constants.ZERO_AMOUNT, | ||||
|             }, | ||||
|         ]; | ||||
|  | ||||
|         defaultPoolId = await treasury.defaultPoolId().callAsync(); | ||||
|         const defaultPoolOperatorAddress = await treasury.defaultPoolOperator().callAsync(); | ||||
|         defaultPoolOperator = new DefaultPoolOperatorContract(defaultPoolOperatorAddress, env.provider, env.txDefaults); | ||||
|     }); | ||||
|     describe('getVotingPower()', () => { | ||||
|         it('Unstaked ZRX has no voting power', async () => { | ||||
| @@ -222,6 +229,19 @@ blockchainTests.resets('Treasury governance', env => { | ||||
|             const operatorVotingPower = await treasury.getVotingPower(poolOperator, [nonDefaultPoolId]).callAsync(); | ||||
|             expect(operatorVotingPower).to.bignumber.equal(TREASURY_PARAMS.proposalThreshold.dividedBy(2)); | ||||
|         }); | ||||
|         it('Reverts if given duplicate pool IDs', async () => { | ||||
|             await staking.stake(TREASURY_PARAMS.proposalThreshold).awaitTransactionSuccessAsync({ from: delegator }); | ||||
|             await staking | ||||
|                 .moveStake( | ||||
|                     new StakeInfo(StakeStatus.Undelegated), | ||||
|                     new StakeInfo(StakeStatus.Delegated, nonDefaultPoolId), | ||||
|                     TREASURY_PARAMS.proposalThreshold, | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: delegator }); | ||||
|             await fastForwardToNextEpochAsync(); | ||||
|             const tx = treasury.getVotingPower(poolOperator, [nonDefaultPoolId, nonDefaultPoolId]).callAsync(); | ||||
|             return expect(tx).to.revertWith('getVotingPower/DUPLICATE_POOL_ID'); | ||||
|         }); | ||||
|         it('Correctly sums voting power delegated to multiple pools', async () => { | ||||
|             await staking | ||||
|                 .stake(TREASURY_PARAMS.proposalThreshold.times(2)) | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619596077, | ||||
|         "version": "4.7.7", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1617311315, | ||||
|         "version": "4.7.6", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.7.7 - _April 28, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.7.6 - _April 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-utils", | ||||
|     "version": "4.7.6", | ||||
|     "version": "4.7.7", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -50,15 +50,15 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@types/bn.js": "^4.11.0", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
| @@ -67,7 +67,7 @@ | ||||
|         "chai-as-promised": "^7.1.0", | ||||
|         "chai-bignumber": "^3.0.0", | ||||
|         "dirty-chai": "^2.0.1", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "lodash": "^4.17.11", | ||||
|         "make-promises-safe": "^1.1.0", | ||||
|         "mocha": "^6.2.0", | ||||
| @@ -79,11 +79,11 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "bn.js": "^4.11.8", | ||||
|         "ethereum-types": "^3.4.0" | ||||
|         "ethereum-types": "^3.5.0" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/con | ||||
| import { BlockchainLifecycle } from '@0x/dev-utils'; | ||||
| import { BigNumber, hexUtils, signTypedDataUtils } from '@0x/utils'; | ||||
| import * as chai from 'chai'; | ||||
| import * as ethUtil from 'ethereumjs-util'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
| @@ -78,7 +77,7 @@ describe('LibEIP712', () => { | ||||
|  | ||||
|         // Hash the provided input to get the expected hash | ||||
|         const input = '0x1901'.concat(unprefixedDomainHash.concat(unprefixedHashStruct)); | ||||
|         const expectedHash = '0x'.concat(ethUtil.sha3(input).toString('hex')); | ||||
|         const expectedHash = hexUtils.hash(input); | ||||
|  | ||||
|         // Get the actual hash by calling the smart contract | ||||
|         const actualHash = await lib.externalHashEIP712Message(domainHash, hashStruct).callAsync(); | ||||
|   | ||||
| @@ -1,10 +1,52 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1619830995, | ||||
|         "version": "0.22.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1619825976, | ||||
|         "version": "0.22.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.22.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "bump feature version to 1.2", | ||||
|                 "pr": 213 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619596077 | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.22.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add order signer registry to NativeOrdersFeature", | ||||
|                 "pr": 195 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619481586 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1618259868, | ||||
|         "version": "0.21.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             }, | ||||
|             { | ||||
|                 "note": "BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap)", | ||||
|                 "pr": 208 | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|   | ||||
| @@ -5,9 +5,26 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v0.22.3 - _May 1, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.22.2 - _April 30, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.22.1 - _April 28, 2021_ | ||||
|  | ||||
|     * bump feature version to 1.2 (#213) | ||||
|  | ||||
| ## v0.22.0 - _April 26, 2021_ | ||||
|  | ||||
|     * Add order signer registry to NativeOrdersFeature (#195) | ||||
|  | ||||
| ## v0.21.1 - _April 12, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|     * BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap) (#208) | ||||
|  | ||||
| ## v0.21.0 - _April 1, 2021_ | ||||
|  | ||||
|   | ||||
| @@ -88,6 +88,21 @@ library LibNativeOrdersRichErrors { | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function InvalidSignerError( | ||||
|         address maker, | ||||
|         address signer | ||||
|     ) | ||||
|         internal | ||||
|         pure | ||||
|         returns (bytes memory) | ||||
|     { | ||||
|         return abi.encodeWithSelector( | ||||
|             bytes4(keccak256("InvalidSignerError(address,address)")), | ||||
|             maker, | ||||
|             signer | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function OrderNotFillableBySenderError( | ||||
|         bytes32 orderHash, | ||||
|         address sender, | ||||
|   | ||||
| @@ -34,7 +34,7 @@ contract NativeOrdersFeature is | ||||
|     /// @dev Name of this feature. | ||||
|     string public constant override FEATURE_NAME = "LimitOrders"; | ||||
|     /// @dev Version of this feature. | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0); | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 2, 0); | ||||
|  | ||||
|     constructor( | ||||
|         address zeroExAddress, | ||||
| @@ -74,9 +74,13 @@ contract NativeOrdersFeature is | ||||
|         _registerFeatureFunction(this.batchCancelLimitOrders.selector); | ||||
|         _registerFeatureFunction(this.batchCancelRfqOrders.selector); | ||||
|         _registerFeatureFunction(this.cancelPairLimitOrders.selector); | ||||
|         _registerFeatureFunction(this.cancelPairLimitOrdersWithSigner.selector); | ||||
|         _registerFeatureFunction(this.batchCancelPairLimitOrders.selector); | ||||
|         _registerFeatureFunction(this.batchCancelPairLimitOrdersWithSigner.selector); | ||||
|         _registerFeatureFunction(this.cancelPairRfqOrders.selector); | ||||
|         _registerFeatureFunction(this.cancelPairRfqOrdersWithSigner.selector); | ||||
|         _registerFeatureFunction(this.batchCancelPairRfqOrders.selector); | ||||
|         _registerFeatureFunction(this.batchCancelPairRfqOrdersWithSigner.selector); | ||||
|         _registerFeatureFunction(this.getLimitOrderInfo.selector); | ||||
|         _registerFeatureFunction(this.getRfqOrderInfo.selector); | ||||
|         _registerFeatureFunction(this.getLimitOrderHash.selector); | ||||
| @@ -87,6 +91,8 @@ contract NativeOrdersFeature is | ||||
|         _registerFeatureFunction(this.getRfqOrderRelevantState.selector); | ||||
|         _registerFeatureFunction(this.batchGetLimitOrderRelevantStates.selector); | ||||
|         _registerFeatureFunction(this.batchGetRfqOrderRelevantStates.selector); | ||||
|         _registerFeatureFunction(this.registerAllowedOrderSigner.selector); | ||||
|         _registerFeatureFunction(this.isValidOrderSigner.selector); | ||||
|         return LibMigrate.MIGRATE_SUCCESS; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -37,22 +37,44 @@ contract PancakeSwapFeature is | ||||
|     /// @dev Name of this feature. | ||||
|     string public constant override FEATURE_NAME = "PancakeSwapFeature"; | ||||
|     /// @dev Version of this feature. | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 1); | ||||
|     uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 2); | ||||
|     /// @dev WBNB contract. | ||||
|     IEtherTokenV06 private immutable WBNB; | ||||
|  | ||||
|     // 0xFF + address of the PancakeSwap factory contract. | ||||
|     uint256 constant private FF_PANCAKESWAP_FACTORY = 0xffbcfccbde45ce874adcb698cc183debcf179528120000000000000000000000; | ||||
|     // 0xFF + address of the PancakeSwapV2 factory contract. | ||||
|     uint256 constant private FF_PANCAKESWAPV2_FACTORY = 0xffca143ce32fe78f1f7019d7d551a6402fc5350c730000000000000000000000; | ||||
|     // 0xFF + address of the BakerySwap factory contract. | ||||
|     uint256 constant private FF_BAKERYSWAP_FACTORY = 0xff01bf7c66c6bd861915cdaae475042d3c4bae16a70000000000000000000000; | ||||
|     // 0xFF + address of the SushiSwap factory contract. | ||||
|     uint256 constant private FF_SUSHISWAP_FACTORY = 0xffc35DADB65012eC5796536bD9864eD8773aBc74C40000000000000000000000; | ||||
|     // 0xFF + address of the ApeSwap factory contract. | ||||
|     uint256 constant private FF_APESWAP_FACTORY = 0xff0841bd0b734e4f5853f0dd8d7ea041c241fb0da60000000000000000000000; | ||||
|     // 0xFF + address of the CafeSwap factory contract. | ||||
|     uint256 constant private FF_CAFESWAP_FACTORY = 0xff3e708fdbe3ada63fc94f8f61811196f1302137ad0000000000000000000000; | ||||
|     // 0xFF + address of the CheeseSwap factory contract. | ||||
|     uint256 constant private FF_CHEESESWAP_FACTORY = 0xffdd538e4fd1b69b7863e1f741213276a6cf1efb3b0000000000000000000000; | ||||
|     // 0xFF + address of the JulSwap factory contract. | ||||
|     uint256 constant private FF_JULSWAP_FACTORY = 0xff553990f2cba90272390f62c5bdb1681ffc8996750000000000000000000000; | ||||
|  | ||||
|     // Init code hash of the PancakeSwap pair contract. | ||||
|     uint256 constant private PANCAKESWAP_PAIR_INIT_CODE_HASH = 0xd0d4c4cd0848c93cb4fd1f498d7013ee6bfb25783ea21593d5834f5d250ece66; | ||||
|     // Init code hash of the PancakeSwapV2 pair contract. | ||||
|     uint256 constant private PANCAKESWAPV2_PAIR_INIT_CODE_HASH = 0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5; | ||||
|     // Init code hash of the BakerySwap pair contract. | ||||
|     uint256 constant private BAKERYSWAP_PAIR_INIT_CODE_HASH = 0xe2e87433120e32c4738a7d8f3271f3d872cbe16241d67537139158d90bac61d3; | ||||
|     // Init code hash of the SushiSwap pair contract. | ||||
|     uint256 constant private SUSHISWAP_PAIR_INIT_CODE_HASH = 0xe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303; | ||||
|     // Init code hash of the ApeSwap pair contract. | ||||
|     uint256 constant private APESWAP_PAIR_INIT_CODE_HASH = 0xf4ccce374816856d11f00e4069e7cada164065686fbef53c6167a63ec2fd8c5b; | ||||
|     // Init code hash of the CafeSwap pair contract. | ||||
|     uint256 constant private CAFESWAP_PAIR_INIT_CODE_HASH = 0x90bcdb5d0bf0e8db3852b0b7d7e05cc8f7c6eb6d511213c5ba02d1d1dbeda8d3; | ||||
|     // Init code hash of the CheeseSwap pair contract. | ||||
|     uint256 constant private CHEESESWAP_PAIR_INIT_CODE_HASH = 0xf52c5189a89e7ca2ef4f19f2798e3900fba7a316de7cef6c5a9446621ba86286; | ||||
|     // Init code hash of the JulSwap pair contract. | ||||
|     uint256 constant private JULSWAP_PAIR_INIT_CODE_HASH = 0xb1e98e21a5335633815a8cfb3b580071c2e4561c50afd57a8746def9ed890b18; | ||||
|  | ||||
|     // Mask of the lower 20 bytes of a bytes32. | ||||
|     uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff; | ||||
|     // BNB pseudo-token address. | ||||
| @@ -258,7 +280,7 @@ contract PancakeSwapFeature is | ||||
|  | ||||
|                 // Call pair.swap() | ||||
|                 switch mload(0xA20) // fork | ||||
|                     case 1 { | ||||
|                     case 2 { | ||||
|                         mstore(0xB00, BAKERYSWAP_PAIR_SWAP_CALL_SELECTOR_32) | ||||
|                     } | ||||
|                     default { | ||||
| @@ -352,15 +374,40 @@ contract PancakeSwapFeature is | ||||
|                         mstore(0xB35, PANCAKESWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     case 1 { | ||||
|                         mstore(0xB00, FF_PANCAKESWAPV2_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, PANCAKESWAPV2_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     case 2 { | ||||
|                         mstore(0xB00, FF_BAKERYSWAP_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, BAKERYSWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     default { | ||||
|                     case 3 { | ||||
|                         mstore(0xB00, FF_SUSHISWAP_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, SUSHISWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     case 4 { | ||||
|                         mstore(0xB00, FF_APESWAP_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, APESWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     case 5 { | ||||
|                         mstore(0xB00, FF_CAFESWAP_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, CAFESWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     case 6 { | ||||
|                         mstore(0xB00, FF_CHEESESWAP_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, CHEESESWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                     default { | ||||
|                         mstore(0xB00, FF_JULSWAP_FACTORY) | ||||
|                         mstore(0xB15, salt) | ||||
|                         mstore(0xB35, JULSWAP_PAIR_INIT_CODE_HASH) | ||||
|                     } | ||||
|                 pair := and(ADDRESS_MASK, keccak256(0xB00, 0x55)) | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -113,4 +113,14 @@ interface INativeOrdersEvents { | ||||
|         address[] addrs, | ||||
|         bool allowed | ||||
|     ); | ||||
|  | ||||
|     /// @dev Emitted when new order signers are registered | ||||
|     /// @param maker The maker address that is registering a designated signer. | ||||
|     /// @param signer The address that will sign on behalf of maker. | ||||
|     /// @param allowed Indicates whether the address should be allowed. | ||||
|     event OrderSignerRegistered( | ||||
|         address maker, | ||||
|         address signer, | ||||
|         bool allowed | ||||
|     ); | ||||
| } | ||||
|   | ||||
| @@ -137,13 +137,13 @@ interface INativeOrdersFeature is | ||||
|         external | ||||
|         returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount); | ||||
|  | ||||
|     /// @dev Cancel a single limit order. The caller must be the maker. | ||||
|     /// @dev Cancel a single limit order. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param order The limit order. | ||||
|     function cancelLimitOrder(LibNativeOrder.LimitOrder calldata order) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel a single RFQ order. The caller must be the maker. | ||||
|     /// @dev Cancel a single RFQ order. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param order The RFQ order. | ||||
|     function cancelRfqOrder(LibNativeOrder.RfqOrder calldata order) | ||||
| @@ -156,13 +156,13 @@ interface INativeOrdersFeature is | ||||
|     function registerAllowedRfqOrigins(address[] memory origins, bool allowed) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel multiple limit orders. The caller must be the maker. | ||||
|     /// @dev Cancel multiple limit orders. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param orders The limit orders. | ||||
|     function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel multiple RFQ orders. The caller must be the maker. | ||||
|     /// @dev Cancel multiple RFQ orders. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param orders The RFQ orders. | ||||
|     function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders) | ||||
| @@ -183,7 +183,23 @@ interface INativeOrdersFeature is | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be the maker. Subsequent | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function cancelPairLimitOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be the maker. Subsequent | ||||
|     ///      calls to this function with the same caller and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param makerTokens The maker tokens. | ||||
| @@ -196,6 +212,22 @@ interface INativeOrdersFeature is | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerTokens The maker tokens. | ||||
|     /// @param takerTokens The taker tokens. | ||||
|     /// @param minValidSalts The new minimum valid salts. | ||||
|     function batchCancelPairLimitOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06[] memory makerTokens, | ||||
|         IERC20TokenV06[] memory takerTokens, | ||||
|         uint256[] memory minValidSalts | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be the maker. Subsequent | ||||
|     ///      calls to this function with the same caller and pair require the | ||||
| @@ -211,7 +243,23 @@ interface INativeOrdersFeature is | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be the maker. Subsequent | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function cancelPairRfqOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be the maker. Subsequent | ||||
|     ///      calls to this function with the same caller and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param makerTokens The maker tokens. | ||||
| @@ -224,6 +272,22 @@ interface INativeOrdersFeature is | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerTokens The maker tokens. | ||||
|     /// @param takerTokens The taker tokens. | ||||
|     /// @param minValidSalts The new minimum valid salts. | ||||
|     function batchCancelPairRfqOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06[] memory makerTokens, | ||||
|         IERC20TokenV06[] memory takerTokens, | ||||
|         uint256[] memory minValidSalts | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev Get the order info for a limit order. | ||||
|     /// @param order The limit order. | ||||
|     /// @return orderInfo Info about the order. | ||||
| @@ -345,4 +409,25 @@ interface INativeOrdersFeature is | ||||
|             uint128[] memory actualFillableTakerTokenAmounts, | ||||
|             bool[] memory isSignatureValids | ||||
|         ); | ||||
|  | ||||
|     /// @dev Register a signer who can sign on behalf of msg.sender | ||||
|     ///      This allows one to sign on behalf of a contract that calls this function | ||||
|     /// @param signer The address from which you plan to generate signatures | ||||
|     /// @param allowed True to register, false to unregister. | ||||
|     function registerAllowedOrderSigner( | ||||
|         address signer, | ||||
|         bool allowed | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
|     /// @dev checks if a given address is registered to sign on behalf of a maker address | ||||
|     /// @param maker The maker address encoded in an order (can be a contract) | ||||
|     /// @param signer The address that is providing a signature | ||||
|     function isValidOrderSigner( | ||||
|         address maker, | ||||
|         address signer | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bool isAllowed); | ||||
| } | ||||
|   | ||||
| @@ -23,16 +23,21 @@ pragma experimental ABIEncoderV2; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
|  | ||||
|  | ||||
| /// @dev VIP PancakeSwap/BakerySwap/SushiSwap fill functions. | ||||
| /// @dev VIP PancakeSwap (and forks) fill functions. | ||||
| interface IPancakeSwapFeature { | ||||
|  | ||||
|     enum ProtocolFork { | ||||
|         PancakeSwap, | ||||
|         PancakeSwapV2, | ||||
|         BakerySwap, | ||||
|         SushiSwap | ||||
|         SushiSwap, | ||||
|         ApeSwap, | ||||
|         CafeSwap, | ||||
|         CheeseSwap, | ||||
|         JulSwap | ||||
|     } | ||||
|  | ||||
|     /// @dev Efficiently sell directly to PancakeSwap/BakerySwap/Sushiswap. | ||||
|     /// @dev Efficiently sell directly to PancakeSwap (and forks). | ||||
|     /// @param tokens Sell path. | ||||
|     /// @param sellAmount of `tokens[0]` Amount to sell. | ||||
|     /// @param minBuyAmount Minimum amount of `tokens[-1]` to buy. | ||||
|   | ||||
| @@ -48,14 +48,14 @@ abstract contract NativeOrdersCancellation is | ||||
|         // solhint-disable no-empty-blocks | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel a single limit order. The caller must be the maker. | ||||
|     /// @dev Cancel a single limit order. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param order The limit order. | ||||
|     function cancelLimitOrder(LibNativeOrder.LimitOrder memory order) | ||||
|         public | ||||
|     { | ||||
|         bytes32 orderHash = getLimitOrderHash(order); | ||||
|         if (msg.sender != order.maker) { | ||||
|         if (msg.sender != order.maker && !isValidOrderSigner(order.maker, msg.sender)) { | ||||
|             LibNativeOrdersRichErrors.OnlyOrderMakerAllowed( | ||||
|                 orderHash, | ||||
|                 msg.sender, | ||||
| @@ -65,14 +65,14 @@ abstract contract NativeOrdersCancellation is | ||||
|         _cancelOrderHash(orderHash, order.maker); | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel a single RFQ order. The caller must be the maker. | ||||
|     /// @dev Cancel a single RFQ order. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param order The RFQ order. | ||||
|     function cancelRfqOrder(LibNativeOrder.RfqOrder memory order) | ||||
|         public | ||||
|     { | ||||
|         bytes32 orderHash = getRfqOrderHash(order); | ||||
|         if (msg.sender != order.maker) { | ||||
|         if (msg.sender != order.maker && !isValidOrderSigner(order.maker, msg.sender)) { | ||||
|             LibNativeOrdersRichErrors.OnlyOrderMakerAllowed( | ||||
|                 orderHash, | ||||
|                 msg.sender, | ||||
| @@ -82,7 +82,7 @@ abstract contract NativeOrdersCancellation is | ||||
|         _cancelOrderHash(orderHash, order.maker); | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel multiple limit orders. The caller must be the maker. | ||||
|     /// @dev Cancel multiple limit orders. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param orders The limit orders. | ||||
|     function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] memory orders) | ||||
| @@ -93,7 +93,7 @@ abstract contract NativeOrdersCancellation is | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel multiple RFQ orders. The caller must be the maker. | ||||
|     /// @dev Cancel multiple RFQ orders. The caller must be the maker or a valid order signer. | ||||
|     ///      Silently succeeds if the order has already been cancelled. | ||||
|     /// @param orders The RFQ orders. | ||||
|     function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] memory orders) | ||||
| @@ -118,33 +118,34 @@ abstract contract NativeOrdersCancellation is | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         LibNativeOrdersStorage.Storage storage stor = | ||||
|             LibNativeOrdersStorage.getStorage(); | ||||
|         _cancelPairLimitOrders(msg.sender, makerToken, takerToken, minValidSalt); | ||||
|     } | ||||
|  | ||||
|         uint256 oldMinValidSalt = | ||||
|             stor.limitOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|                 [msg.sender] | ||||
|                 [address(makerToken)] | ||||
|                 [address(takerToken)]; | ||||
|  | ||||
|         // New min salt must >= the old one. | ||||
|         if (oldMinValidSalt > minValidSalt) { | ||||
|             LibNativeOrdersRichErrors. | ||||
|                 CancelSaltTooLowError(minValidSalt, oldMinValidSalt) | ||||
|                     .rrevert(); | ||||
|     /// @dev Cancel all limit orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same caller and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker the maker for whom the msg.sender is the signer. | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function cancelPairLimitOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         // verify that the signer is authorized for the maker | ||||
|         if (!isValidOrderSigner(maker, msg.sender)) { | ||||
|             LibNativeOrdersRichErrors.InvalidSignerError( | ||||
|                 maker, | ||||
|                 msg.sender | ||||
|             ).rrevert(); | ||||
|         } | ||||
|  | ||||
|         stor.limitOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|             [msg.sender] | ||||
|             [address(makerToken)] | ||||
|             [address(takerToken)] = minValidSalt; | ||||
|  | ||||
|         emit PairCancelledLimitOrders( | ||||
|             msg.sender, | ||||
|             address(makerToken), | ||||
|             address(takerToken), | ||||
|             minValidSalt | ||||
|         ); | ||||
|         _cancelPairLimitOrders(maker, makerToken, takerToken, minValidSalt); | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pair with a salt less | ||||
| @@ -168,7 +169,47 @@ abstract contract NativeOrdersCancellation is | ||||
|         ); | ||||
|  | ||||
|         for (uint256 i = 0; i < makerTokens.length; ++i) { | ||||
|             cancelPairLimitOrders( | ||||
|             _cancelPairLimitOrders( | ||||
|                 msg.sender, | ||||
|                 makerTokens[i], | ||||
|                 takerTokens[i], | ||||
|                 minValidSalts[i] | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same caller and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker the maker for whom the msg.sender is the signer. | ||||
|     /// @param makerTokens The maker tokens. | ||||
|     /// @param takerTokens The taker tokens. | ||||
|     /// @param minValidSalts The new minimum valid salts. | ||||
|     function batchCancelPairLimitOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06[] memory makerTokens, | ||||
|         IERC20TokenV06[] memory takerTokens, | ||||
|         uint256[] memory minValidSalts | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         require( | ||||
|             makerTokens.length == takerTokens.length && | ||||
|             makerTokens.length == minValidSalts.length, | ||||
|             "NativeOrdersFeature/MISMATCHED_PAIR_ORDERS_ARRAY_LENGTHS" | ||||
|         ); | ||||
|  | ||||
|         if (!isValidOrderSigner(maker, msg.sender)) { | ||||
|             LibNativeOrdersRichErrors.InvalidSignerError( | ||||
|                 maker, | ||||
|                 msg.sender | ||||
|             ).rrevert(); | ||||
|         } | ||||
|  | ||||
|         for (uint256 i = 0; i < makerTokens.length; ++i) { | ||||
|             _cancelPairLimitOrders( | ||||
|                 maker, | ||||
|                 makerTokens[i], | ||||
|                 takerTokens[i], | ||||
|                 minValidSalts[i] | ||||
| @@ -190,33 +231,33 @@ abstract contract NativeOrdersCancellation is | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         LibNativeOrdersStorage.Storage storage stor = | ||||
|             LibNativeOrdersStorage.getStorage(); | ||||
|         _cancelPairRfqOrders(msg.sender, makerToken, takerToken, minValidSalt); | ||||
|     } | ||||
|  | ||||
|         uint256 oldMinValidSalt = | ||||
|             stor.rfqOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|                 [msg.sender] | ||||
|                 [address(makerToken)] | ||||
|                 [address(takerToken)]; | ||||
|  | ||||
|         // New min salt must >= the old one. | ||||
|         if (oldMinValidSalt > minValidSalt) { | ||||
|             LibNativeOrdersRichErrors. | ||||
|                 CancelSaltTooLowError(minValidSalt, oldMinValidSalt) | ||||
|                     .rrevert(); | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same caller and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker the maker for whom the msg.sender is the signer. | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function cancelPairRfqOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         if (!isValidOrderSigner(maker, msg.sender)) { | ||||
|             LibNativeOrdersRichErrors.InvalidSignerError( | ||||
|                 maker, | ||||
|                 msg.sender | ||||
|             ).rrevert(); | ||||
|         } | ||||
|  | ||||
|         stor.rfqOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|             [msg.sender] | ||||
|             [address(makerToken)] | ||||
|             [address(takerToken)] = minValidSalt; | ||||
|  | ||||
|         emit PairCancelledRfqOrders( | ||||
|             msg.sender, | ||||
|             address(makerToken), | ||||
|             address(takerToken), | ||||
|             minValidSalt | ||||
|         ); | ||||
|         _cancelPairRfqOrders(maker, makerToken, takerToken, minValidSalt); | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pair with a salt less | ||||
| @@ -240,7 +281,47 @@ abstract contract NativeOrdersCancellation is | ||||
|         ); | ||||
|  | ||||
|         for (uint256 i = 0; i < makerTokens.length; ++i) { | ||||
|             cancelPairRfqOrders( | ||||
|             _cancelPairRfqOrders( | ||||
|                 msg.sender, | ||||
|                 makerTokens[i], | ||||
|                 takerTokens[i], | ||||
|                 minValidSalts[i] | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same caller and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker the maker for whom the msg.sender is the signer. | ||||
|     /// @param makerTokens The maker tokens. | ||||
|     /// @param takerTokens The taker tokens. | ||||
|     /// @param minValidSalts The new minimum valid salts. | ||||
|     function batchCancelPairRfqOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06[] memory makerTokens, | ||||
|         IERC20TokenV06[] memory takerTokens, | ||||
|         uint256[] memory minValidSalts | ||||
|     ) | ||||
|         public | ||||
|     { | ||||
|         require( | ||||
|             makerTokens.length == takerTokens.length && | ||||
|             makerTokens.length == minValidSalts.length, | ||||
|             "NativeOrdersFeature/MISMATCHED_PAIR_ORDERS_ARRAY_LENGTHS" | ||||
|         ); | ||||
|  | ||||
|         if (!isValidOrderSigner(maker, msg.sender)) { | ||||
|             LibNativeOrdersRichErrors.InvalidSignerError( | ||||
|                 maker, | ||||
|                 msg.sender | ||||
|             ).rrevert(); | ||||
|         } | ||||
|  | ||||
|         for (uint256 i = 0; i < makerTokens.length; ++i) { | ||||
|             _cancelPairRfqOrders( | ||||
|                 maker, | ||||
|                 makerTokens[i], | ||||
|                 takerTokens[i], | ||||
|                 minValidSalts[i] | ||||
| @@ -262,4 +343,90 @@ abstract contract NativeOrdersCancellation is | ||||
|  | ||||
|         emit OrderCancelled(orderHash, maker); | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. | ||||
|     /// @param maker The target maker address | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function _cancelPairRfqOrders( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         private | ||||
|     { | ||||
|         LibNativeOrdersStorage.Storage storage stor = | ||||
|             LibNativeOrdersStorage.getStorage(); | ||||
|  | ||||
|         uint256 oldMinValidSalt = | ||||
|             stor.rfqOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|                 [maker] | ||||
|                 [address(makerToken)] | ||||
|                 [address(takerToken)]; | ||||
|  | ||||
|         // New min salt must >= the old one. | ||||
|         if (oldMinValidSalt > minValidSalt) { | ||||
|             LibNativeOrdersRichErrors. | ||||
|                 CancelSaltTooLowError(minValidSalt, oldMinValidSalt) | ||||
|                     .rrevert(); | ||||
|         } | ||||
|  | ||||
|         stor.rfqOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|             [maker] | ||||
|             [address(makerToken)] | ||||
|             [address(takerToken)] = minValidSalt; | ||||
|  | ||||
|         emit PairCancelledRfqOrders( | ||||
|             maker, | ||||
|             address(makerToken), | ||||
|             address(takerToken), | ||||
|             minValidSalt | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. | ||||
|     /// @param maker The target maker address | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function _cancelPairLimitOrders( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         private | ||||
|     { | ||||
|         LibNativeOrdersStorage.Storage storage stor = | ||||
|             LibNativeOrdersStorage.getStorage(); | ||||
|  | ||||
|         uint256 oldMinValidSalt = | ||||
|             stor.limitOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|                 [maker] | ||||
|                 [address(makerToken)] | ||||
|                 [address(takerToken)]; | ||||
|  | ||||
|         // New min salt must >= the old one. | ||||
|         if (oldMinValidSalt > minValidSalt) { | ||||
|             LibNativeOrdersRichErrors. | ||||
|                 CancelSaltTooLowError(minValidSalt, oldMinValidSalt) | ||||
|                     .rrevert(); | ||||
|         } | ||||
|  | ||||
|         stor.limitOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt | ||||
|             [maker] | ||||
|             [address(makerToken)] | ||||
|             [address(takerToken)] = minValidSalt; | ||||
|  | ||||
|         emit PairCancelledLimitOrders( | ||||
|             maker, | ||||
|             address(makerToken), | ||||
|             address(takerToken), | ||||
|             minValidSalt | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -168,8 +168,10 @@ abstract contract NativeOrdersInfo is | ||||
|                 orderInfo: orderInfo | ||||
|             }) | ||||
|         ); | ||||
|         isSignatureValid = order.maker == | ||||
|             LibSignature.getSignerOfHash(orderInfo.orderHash, signature); | ||||
|         address signerOfHash = LibSignature.getSignerOfHash(orderInfo.orderHash, signature); | ||||
|         isSignatureValid = | ||||
|             (order.maker == signerOfHash) || | ||||
|             isValidOrderSigner(order.maker, signerOfHash); | ||||
|     } | ||||
|  | ||||
|     /// @dev Get order info, fillable amount, and signature validity for an RFQ order. | ||||
| @@ -202,8 +204,10 @@ abstract contract NativeOrdersInfo is | ||||
|                 orderInfo: orderInfo | ||||
|             }) | ||||
|         ); | ||||
|         isSignatureValid = order.maker == | ||||
|             LibSignature.getSignerOfHash(orderInfo.orderHash, signature); | ||||
|         address signerOfHash = LibSignature.getSignerOfHash(orderInfo.orderHash, signature); | ||||
|         isSignatureValid = | ||||
|             (order.maker == signerOfHash) || | ||||
|             isValidOrderSigner(order.maker, signerOfHash); | ||||
|     } | ||||
|  | ||||
|     /// @dev Batch version of `getLimitOrderRelevantState()`, without reverting. | ||||
| @@ -389,4 +393,22 @@ abstract contract NativeOrdersInfo is | ||||
|             uint256(params.orderTakerAmount) | ||||
|         ).safeDowncastToUint128(); | ||||
|     } | ||||
|  | ||||
|     /// @dev checks if a given address is registered to sign on behalf of a maker address | ||||
|     /// @param maker The maker address encoded in an order (can be a contract) | ||||
|     /// @param signer The address that is providing a signature | ||||
|     function isValidOrderSigner( | ||||
|         address maker, | ||||
|         address signer | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (bool isValid) | ||||
|     { | ||||
|         // returns false if it the mapping doesn't exist | ||||
|         return LibNativeOrdersStorage.getStorage() | ||||
|             .orderSignerRegistry | ||||
|                 [maker] | ||||
|                 [signer]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -370,7 +370,7 @@ abstract contract NativeOrdersSettlement is | ||||
|                 orderInfo.orderHash, | ||||
|                 params.signature | ||||
|             ); | ||||
|             if (signer != params.order.maker) { | ||||
|             if (signer != params.order.maker && !isValidOrderSigner(params.order.maker, signer)) { | ||||
|                 LibNativeOrdersRichErrors.OrderNotSignedByMakerError( | ||||
|                     orderInfo.orderHash, | ||||
|                     signer, | ||||
| @@ -478,7 +478,7 @@ abstract contract NativeOrdersSettlement is | ||||
|         // Signature must be valid for the order. | ||||
|         { | ||||
|             address signer = LibSignature.getSignerOfHash(orderInfo.orderHash, signature); | ||||
|             if (signer != order.maker) { | ||||
|             if (signer != order.maker && !isValidOrderSigner(order.maker, signer)) { | ||||
|                 LibNativeOrdersRichErrors.OrderNotSignedByMakerError( | ||||
|                     orderInfo.orderHash, | ||||
|                     signer, | ||||
| @@ -565,4 +565,21 @@ abstract contract NativeOrdersSettlement is | ||||
|             makerTokenFilledAmount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /// @dev register a signer who can sign on behalf of msg.sender | ||||
|     /// @param signer The address from which you plan to generate signatures | ||||
|     /// @param allowed True to register, false to unregister. | ||||
|     function registerAllowedOrderSigner( | ||||
|         address signer, | ||||
|         bool allowed | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         LibNativeOrdersStorage.Storage storage stor = | ||||
|             LibNativeOrdersStorage.getStorage(); | ||||
|  | ||||
|         stor.orderSignerRegistry[msg.sender][signer] = allowed; | ||||
|  | ||||
|         emit OrderSignerRegistered(msg.sender, signer, allowed); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -43,6 +43,9 @@ library LibNativeOrdersStorage { | ||||
|         // For a given order origin, which tx.origin addresses are allowed to | ||||
|         // fill the order. | ||||
|         mapping(address => mapping(address => bool)) originRegistry; | ||||
|         // For a given maker address, which addresses are allowed to | ||||
|         // sign on its behalf. | ||||
|         mapping(address => mapping(address => bool)) orderSignerRegistry; | ||||
|     } | ||||
|  | ||||
|     /// @dev Get the storage bucket for this contract. | ||||
|   | ||||
| @@ -0,0 +1,55 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| /* | ||||
|  | ||||
|   Copyright 2021 ZeroEx Intl. | ||||
|  | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
|   You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|   Unless required by applicable law or agreed to in writing, software | ||||
|   distributed under the License is distributed on an "AS IS" BASIS, | ||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|   See the License for the specific language governing permissions and | ||||
|   limitations under the License. | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.6.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-utils/contracts/src/v06/OwnableV06.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "../src/IZeroEx.sol"; | ||||
|  | ||||
| contract TestOrderSignerRegistryWithContractWallet is OwnableV06 { | ||||
|  | ||||
|     IZeroEx immutable zeroex; | ||||
|  | ||||
|     constructor(IZeroEx _zeroex) public { | ||||
|         zeroex = _zeroex; | ||||
|     } | ||||
|  | ||||
|     function registerAllowedOrderSigner( | ||||
|         address signer, | ||||
|         bool allowed | ||||
|     ) | ||||
|         external | ||||
|         onlyOwner | ||||
|     { | ||||
|         zeroex.registerAllowedOrderSigner(signer, allowed); | ||||
|     } | ||||
|  | ||||
|     function approveERC20( | ||||
|         IERC20TokenV06 token, | ||||
|         address spender, | ||||
|         uint256 value | ||||
|     ) | ||||
|         external | ||||
|         onlyOwner | ||||
|     { | ||||
|         token.approve(spender, value); | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-zero-ex", | ||||
|     "version": "0.21.1", | ||||
|     "version": "0.22.3", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -43,7 +43,7 @@ | ||||
|     "config": { | ||||
|         "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", | ||||
|         "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinDodoV2|MixinKyber|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json" | ||||
|         "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinDodoV2|MixinKyber|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json" | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
| @@ -55,16 +55,16 @@ | ||||
|     }, | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.4.21", | ||||
|         "@0x/abi-gen": "^5.5.2", | ||||
|         "@0x/contract-addresses": "^6.0.0", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/order-utils": "^10.4.19", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/order-utils": "^10.4.20", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@types/isomorphic-fetch": "^0.0.35", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
| @@ -82,15 +82,15 @@ | ||||
|         "typescript": "4.2.2" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/protocol-utils": "^1.4.1", | ||||
|         "@0x/subproviders": "^6.4.1", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^5.1.1" | ||||
|         "@0x/base-contract": "^6.3.2", | ||||
|         "@0x/protocol-utils": "^1.5.1", | ||||
|         "@0x/subproviders": "^6.5.2", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10" | ||||
|     }, | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|   | ||||
| @@ -20,6 +20,7 @@ export function rlpEncodeNonce(nonce: number): string { | ||||
|         return ethjs.bufferToHex(ethjs.toBuffer(nonce)); | ||||
|     } else { | ||||
|         const rlpNonce = ethjs.toBuffer(nonce); | ||||
|         // tslint:disable-next-line: restrict-plus-operands | ||||
|         return hexUtils.concat(rlpNonce.length + 0x80, ethjs.bufferToHex(rlpNonce)); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -127,6 +127,7 @@ import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintabl | ||||
| import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json'; | ||||
| import * as TestMooniswap from '../test/generated-artifacts/TestMooniswap.json'; | ||||
| import * as TestNativeOrdersFeature from '../test/generated-artifacts/TestNativeOrdersFeature.json'; | ||||
| import * as TestOrderSignerRegistryWithContractWallet from '../test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json'; | ||||
| import * as TestPermissionlessTransformerDeployerSuicidal from '../test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json'; | ||||
| import * as TestPermissionlessTransformerDeployerTransformer from '../test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json'; | ||||
| import * as TestRfqOriginRegistration from '../test/generated-artifacts/TestRfqOriginRegistration.json'; | ||||
| @@ -278,6 +279,7 @@ export const artifacts = { | ||||
|     TestMintableERC20Token: TestMintableERC20Token as ContractArtifact, | ||||
|     TestMooniswap: TestMooniswap as ContractArtifact, | ||||
|     TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact, | ||||
|     TestOrderSignerRegistryWithContractWallet: TestOrderSignerRegistryWithContractWallet as ContractArtifact, | ||||
|     TestPermissionlessTransformerDeployerSuicidal: TestPermissionlessTransformerDeployerSuicidal as ContractArtifact, | ||||
|     TestPermissionlessTransformerDeployerTransformer: TestPermissionlessTransformerDeployerTransformer as ContractArtifact, | ||||
|     TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact, | ||||
|   | ||||
| @@ -7,7 +7,15 @@ import { | ||||
|     randomAddress, | ||||
|     verifyEventsFromLogs, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { LimitOrder, LimitOrderFields, OrderStatus, RevertErrors, RfqOrder, RfqOrderFields } from '@0x/protocol-utils'; | ||||
| import { | ||||
|     LimitOrder, | ||||
|     LimitOrderFields, | ||||
|     OrderStatus, | ||||
|     RevertErrors, | ||||
|     RfqOrder, | ||||
|     RfqOrderFields, | ||||
|     SignatureType, | ||||
| } from '@0x/protocol-utils'; | ||||
| import { AnyRevertError, BigNumber } from '@0x/utils'; | ||||
| import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; | ||||
|  | ||||
| @@ -25,7 +33,11 @@ import { | ||||
|     getRandomRfqOrder, | ||||
|     NativeOrdersTestEnvironment, | ||||
| } from '../utils/orders'; | ||||
| import { TestMintableERC20TokenContract, TestRfqOriginRegistrationContract } from '../wrappers'; | ||||
| import { | ||||
|     TestMintableERC20TokenContract, | ||||
|     TestOrderSignerRegistryWithContractWalletContract, | ||||
|     TestRfqOriginRegistrationContract, | ||||
| } from '../wrappers'; | ||||
|  | ||||
| blockchainTests.resets('NativeOrdersFeature', env => { | ||||
|     const { NULL_ADDRESS, MAX_UINT256, NULL_BYTES32, ZERO_AMOUNT } = constants; | ||||
| @@ -36,17 +48,28 @@ blockchainTests.resets('NativeOrdersFeature', env => { | ||||
|     let taker: string; | ||||
|     let notMaker: string; | ||||
|     let notTaker: string; | ||||
|     let contractWalletOwner: string; | ||||
|     let contractWalletSigner: string; | ||||
|     let zeroEx: IZeroExContract; | ||||
|     let verifyingContract: string; | ||||
|     let makerToken: TestMintableERC20TokenContract; | ||||
|     let takerToken: TestMintableERC20TokenContract; | ||||
|     let wethToken: TestMintableERC20TokenContract; | ||||
|     let testRfqOriginRegistration: TestRfqOriginRegistrationContract; | ||||
|     let contractWallet: TestOrderSignerRegistryWithContractWalletContract; | ||||
|     let testUtils: NativeOrdersTestEnvironment; | ||||
|  | ||||
|     before(async () => { | ||||
|         let owner; | ||||
|         [owner, maker, taker, notMaker, notTaker] = await env.getAccountAddressesAsync(); | ||||
|         [ | ||||
|             owner, | ||||
|             maker, | ||||
|             taker, | ||||
|             notMaker, | ||||
|             notTaker, | ||||
|             contractWalletOwner, | ||||
|             contractWalletSigner, | ||||
|         ] = await env.getAccountAddressesAsync(); | ||||
|         [makerToken, takerToken, wethToken] = await Promise.all( | ||||
|             [...new Array(3)].map(async () => | ||||
|                 TestMintableERC20TokenContract.deployFrom0xArtifactAsync( | ||||
| @@ -82,6 +105,21 @@ blockchainTests.resets('NativeOrdersFeature', env => { | ||||
|             env.txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|         // contract wallet for signer delegation | ||||
|         contractWallet = await TestOrderSignerRegistryWithContractWalletContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestOrderSignerRegistryWithContractWallet, | ||||
|             env.provider, | ||||
|             { | ||||
|                 from: contractWalletOwner, | ||||
|             }, | ||||
|             artifacts, | ||||
|             zeroEx.address, | ||||
|         ); | ||||
|  | ||||
|         await contractWallet | ||||
|             .approveERC20(makerToken.address, zeroEx.address, MAX_UINT256) | ||||
|             .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|         testUtils = new NativeOrdersTestEnvironment( | ||||
|             maker, | ||||
|             taker, | ||||
| @@ -1569,4 +1607,432 @@ blockchainTests.resets('NativeOrdersFeature', env => { | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('registerAllowedSigner()', () => { | ||||
|         it('fires appropriate events', async () => { | ||||
|             const receiptAllow = await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             verifyEventsFromLogs( | ||||
|                 receiptAllow.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         signer: contractWalletSigner, | ||||
|                         allowed: true, | ||||
|                     }, | ||||
|                 ], | ||||
|                 IZeroExEvents.OrderSignerRegistered, | ||||
|             ); | ||||
|  | ||||
|             // then disallow signer | ||||
|             const receiptDisallow = await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, false) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             verifyEventsFromLogs( | ||||
|                 receiptDisallow.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         signer: contractWalletSigner, | ||||
|                         allowed: false, | ||||
|                     }, | ||||
|                 ], | ||||
|                 IZeroExEvents.OrderSignerRegistered, | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it('allows for fills on orders signed by a approved signer', async () => { | ||||
|             const order = getTestRfqOrder({ maker: contractWallet.address }); | ||||
|             const sig = await order.getSignatureWithProviderAsync( | ||||
|                 env.provider, | ||||
|                 SignatureType.EthSign, | ||||
|                 contractWalletSigner, | ||||
|             ); | ||||
|  | ||||
|             // covers taker | ||||
|             await testUtils.prepareBalancesForOrdersAsync([order]); | ||||
|             // need to provide contract wallet with a balance | ||||
|             await makerToken.mint(contractWallet.address, order.makerAmount).awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             await zeroEx.fillRfqOrder(order, sig, order.takerAmount).awaitTransactionSuccessAsync({ from: taker }); | ||||
|  | ||||
|             const info = await zeroEx.getRfqOrderInfo(order).callAsync(); | ||||
|             assertOrderInfoEquals(info, { | ||||
|                 status: OrderStatus.Filled, | ||||
|                 orderHash: order.getHash(), | ||||
|                 takerTokenFilledAmount: order.takerAmount, | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it('disallows fills if the signer is revoked', async () => { | ||||
|             const order = getTestRfqOrder({ maker: contractWallet.address }); | ||||
|             const sig = await order.getSignatureWithProviderAsync( | ||||
|                 env.provider, | ||||
|                 SignatureType.EthSign, | ||||
|                 contractWalletSigner, | ||||
|             ); | ||||
|  | ||||
|             // covers taker | ||||
|             await testUtils.prepareBalancesForOrdersAsync([order]); | ||||
|             // need to provide contract wallet with a balance | ||||
|             await makerToken.mint(contractWallet.address, order.makerAmount).awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // first allow signer | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             // then disallow signer | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, false) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             const tx = zeroEx.fillRfqOrder(order, sig, order.takerAmount).awaitTransactionSuccessAsync({ from: taker }); | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.OrderNotSignedByMakerError( | ||||
|                     order.getHash(), | ||||
|                     contractWalletSigner, | ||||
|                     order.maker, | ||||
|                 ), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow fills with an unapproved signer`, async () => { | ||||
|             const order = getTestRfqOrder({ maker: contractWallet.address }); | ||||
|             const sig = await order.getSignatureWithProviderAsync(env.provider, SignatureType.EthSign, maker); | ||||
|  | ||||
|             // covers taker | ||||
|             await testUtils.prepareBalancesForOrdersAsync([order]); | ||||
|             // need to provide contract wallet with a balance | ||||
|             await makerToken.mint(contractWallet.address, order.makerAmount).awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             const tx = zeroEx.fillRfqOrder(order, sig, order.takerAmount).awaitTransactionSuccessAsync({ from: taker }); | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.OrderNotSignedByMakerError(order.getHash(), maker, order.maker), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`allows an approved signer to cancel an RFQ order`, async () => { | ||||
|             const order = getTestRfqOrder({ maker: contractWallet.address }); | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             const receipt = await zeroEx | ||||
|                 .cancelRfqOrder(order) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletSigner }); | ||||
|  | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [{ maker: contractWallet.address, orderHash: order.getHash() }], | ||||
|                 IZeroExEvents.OrderCancelled, | ||||
|             ); | ||||
|  | ||||
|             const info = await zeroEx.getRfqOrderInfo(order).callAsync(); | ||||
|             assertOrderInfoEquals(info, { | ||||
|                 status: OrderStatus.Cancelled, | ||||
|                 orderHash: order.getHash(), | ||||
|                 takerTokenFilledAmount: new BigNumber(0), | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it(`allows an approved signer to cancel a limit order`, async () => { | ||||
|             const order = getTestLimitOrder({ maker: contractWallet.address }); | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             const receipt = await zeroEx | ||||
|                 .cancelLimitOrder(order) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletSigner }); | ||||
|  | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [{ maker: contractWallet.address, orderHash: order.getHash() }], | ||||
|                 IZeroExEvents.OrderCancelled, | ||||
|             ); | ||||
|  | ||||
|             const info = await zeroEx.getLimitOrderInfo(order).callAsync(); | ||||
|             assertOrderInfoEquals(info, { | ||||
|                 status: OrderStatus.Cancelled, | ||||
|                 orderHash: order.getHash(), | ||||
|                 takerTokenFilledAmount: new BigNumber(0), | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow an unapproved signer to cancel an RFQ order`, async () => { | ||||
|             const order = getTestRfqOrder({ maker: contractWallet.address }); | ||||
|  | ||||
|             const tx = zeroEx.cancelRfqOrder(order).awaitTransactionSuccessAsync({ from: maker }); | ||||
|  | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.OnlyOrderMakerAllowed(order.getHash(), maker, order.maker), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow an unapproved signer to cancel a limit order`, async () => { | ||||
|             const order = getTestLimitOrder({ maker: contractWallet.address }); | ||||
|  | ||||
|             const tx = zeroEx.cancelLimitOrder(order).awaitTransactionSuccessAsync({ from: maker }); | ||||
|  | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.OnlyOrderMakerAllowed(order.getHash(), maker, order.maker), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`allows a signer to cancel pair RFQ orders`, async () => { | ||||
|             const order = getTestRfqOrder({ maker: contractWallet.address, salt: new BigNumber(1) }); | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             // Cancel salts <= the order's | ||||
|             const minValidSalt = order.salt.plus(1); | ||||
|  | ||||
|             const receipt = await zeroEx | ||||
|                 .cancelPairRfqOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     makerToken.address, | ||||
|                     takerToken.address, | ||||
|                     minValidSalt, | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletSigner }); | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         makerToken: makerToken.address, | ||||
|                         takerToken: takerToken.address, | ||||
|                         minValidSalt, | ||||
|                     }, | ||||
|                 ], | ||||
|                 IZeroExEvents.PairCancelledRfqOrders, | ||||
|             ); | ||||
|  | ||||
|             const info = await zeroEx.getRfqOrderInfo(order).callAsync(); | ||||
|  | ||||
|             assertOrderInfoEquals(info, { | ||||
|                 status: OrderStatus.Cancelled, | ||||
|                 orderHash: order.getHash(), | ||||
|                 takerTokenFilledAmount: new BigNumber(0), | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow an unapproved signer to cancel pair RFQ orders`, async () => { | ||||
|             const minValidSalt = new BigNumber(2); | ||||
|  | ||||
|             const tx = zeroEx | ||||
|                 .cancelPairRfqOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     makerToken.address, | ||||
|                     takerToken.address, | ||||
|                     minValidSalt, | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: maker }); | ||||
|  | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.InvalidSignerError(contractWallet.address, maker), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`allows a signer to cancel pair limit orders`, async () => { | ||||
|             const order = getTestLimitOrder({ maker: contractWallet.address, salt: new BigNumber(1) }); | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             // Cancel salts <= the order's | ||||
|             const minValidSalt = order.salt.plus(1); | ||||
|  | ||||
|             const receipt = await zeroEx | ||||
|                 .cancelPairLimitOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     makerToken.address, | ||||
|                     takerToken.address, | ||||
|                     minValidSalt, | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletSigner }); | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         makerToken: makerToken.address, | ||||
|                         takerToken: takerToken.address, | ||||
|                         minValidSalt, | ||||
|                     }, | ||||
|                 ], | ||||
|                 IZeroExEvents.PairCancelledLimitOrders, | ||||
|             ); | ||||
|  | ||||
|             const info = await zeroEx.getLimitOrderInfo(order).callAsync(); | ||||
|  | ||||
|             assertOrderInfoEquals(info, { | ||||
|                 status: OrderStatus.Cancelled, | ||||
|                 orderHash: order.getHash(), | ||||
|                 takerTokenFilledAmount: new BigNumber(0), | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow an unapproved signer to cancel pair limit orders`, async () => { | ||||
|             const minValidSalt = new BigNumber(2); | ||||
|  | ||||
|             const tx = zeroEx | ||||
|                 .cancelPairLimitOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     makerToken.address, | ||||
|                     takerToken.address, | ||||
|                     minValidSalt, | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: maker }); | ||||
|  | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.InvalidSignerError(contractWallet.address, maker), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`allows a signer to cancel multiple RFQ order pairs`, async () => { | ||||
|             const orders = [ | ||||
|                 getTestRfqOrder({ maker: contractWallet.address, salt: new BigNumber(1) }), | ||||
|                 // Flip the tokens for the other order. | ||||
|                 getTestRfqOrder({ | ||||
|                     makerToken: takerToken.address, | ||||
|                     takerToken: makerToken.address, | ||||
|                     maker: contractWallet.address, | ||||
|                     salt: new BigNumber(1), | ||||
|                 }), | ||||
|             ]; | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             const minValidSalt = new BigNumber(2); | ||||
|             const receipt = await zeroEx | ||||
|                 .batchCancelPairRfqOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     [makerToken.address, takerToken.address], | ||||
|                     [takerToken.address, makerToken.address], | ||||
|                     [minValidSalt, minValidSalt], | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletSigner }); | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         makerToken: makerToken.address, | ||||
|                         takerToken: takerToken.address, | ||||
|                         minValidSalt, | ||||
|                     }, | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         makerToken: takerToken.address, | ||||
|                         takerToken: makerToken.address, | ||||
|                         minValidSalt, | ||||
|                     }, | ||||
|                 ], | ||||
|                 IZeroExEvents.PairCancelledRfqOrders, | ||||
|             ); | ||||
|             const statuses = (await Promise.all(orders.map(o => zeroEx.getRfqOrderInfo(o).callAsync()))).map( | ||||
|                 oi => oi.status, | ||||
|             ); | ||||
|             expect(statuses).to.deep.eq([OrderStatus.Cancelled, OrderStatus.Cancelled]); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow an unapproved signer to batch cancel pair rfq orders`, async () => { | ||||
|             const minValidSalt = new BigNumber(2); | ||||
|  | ||||
|             const tx = zeroEx | ||||
|                 .batchCancelPairRfqOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     [makerToken.address, takerToken.address], | ||||
|                     [takerToken.address, makerToken.address], | ||||
|                     [minValidSalt, minValidSalt], | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: maker }); | ||||
|  | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.InvalidSignerError(contractWallet.address, maker), | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it(`allows a signer to cancel multiple limit order pairs`, async () => { | ||||
|             const orders = [ | ||||
|                 getTestLimitOrder({ maker: contractWallet.address, salt: new BigNumber(1) }), | ||||
|                 // Flip the tokens for the other order. | ||||
|                 getTestLimitOrder({ | ||||
|                     makerToken: takerToken.address, | ||||
|                     takerToken: makerToken.address, | ||||
|                     maker: contractWallet.address, | ||||
|                     salt: new BigNumber(1), | ||||
|                 }), | ||||
|             ]; | ||||
|  | ||||
|             await contractWallet | ||||
|                 .registerAllowedOrderSigner(contractWalletSigner, true) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletOwner }); | ||||
|  | ||||
|             const minValidSalt = new BigNumber(2); | ||||
|             const receipt = await zeroEx | ||||
|                 .batchCancelPairLimitOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     [makerToken.address, takerToken.address], | ||||
|                     [takerToken.address, makerToken.address], | ||||
|                     [minValidSalt, minValidSalt], | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: contractWalletSigner }); | ||||
|             verifyEventsFromLogs( | ||||
|                 receipt.logs, | ||||
|                 [ | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         makerToken: makerToken.address, | ||||
|                         takerToken: takerToken.address, | ||||
|                         minValidSalt, | ||||
|                     }, | ||||
|                     { | ||||
|                         maker: contractWallet.address, | ||||
|                         makerToken: takerToken.address, | ||||
|                         takerToken: makerToken.address, | ||||
|                         minValidSalt, | ||||
|                     }, | ||||
|                 ], | ||||
|                 IZeroExEvents.PairCancelledLimitOrders, | ||||
|             ); | ||||
|             const statuses = (await Promise.all(orders.map(o => zeroEx.getLimitOrderInfo(o).callAsync()))).map( | ||||
|                 oi => oi.status, | ||||
|             ); | ||||
|             expect(statuses).to.deep.eq([OrderStatus.Cancelled, OrderStatus.Cancelled]); | ||||
|         }); | ||||
|  | ||||
|         it(`doesn't allow an unapproved signer to batch cancel pair limit orders`, async () => { | ||||
|             const minValidSalt = new BigNumber(2); | ||||
|  | ||||
|             const tx = zeroEx | ||||
|                 .batchCancelPairLimitOrdersWithSigner( | ||||
|                     contractWallet.address, | ||||
|                     [makerToken.address, takerToken.address], | ||||
|                     [takerToken.address, makerToken.address], | ||||
|                     [minValidSalt, minValidSalt], | ||||
|                 ) | ||||
|                 .awaitTransactionSuccessAsync({ from: maker }); | ||||
|  | ||||
|             return expect(tx).to.revertWith( | ||||
|                 new RevertErrors.NativeOrders.InvalidSignerError(contractWallet.address, maker), | ||||
|             ); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| import { blockchainTests, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils'; | ||||
| import { BigNumber, hexUtils } from '@0x/utils'; | ||||
| import * as ethjs from 'ethereumjs-util'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
| import { | ||||
| @@ -41,9 +40,9 @@ blockchainTests.resets('PermissionlessTransformerDeployer', env => { | ||||
|         it('deploys at predictable address', async () => { | ||||
|             const salt = hexUtils.random(); | ||||
|             const targetAddress = await deployer.deploy(deployBytes, salt).callAsync(); | ||||
|             const initCodeHash = hexUtils.toHex(ethjs.sha3(deployBytes)); | ||||
|             const initCodeHash = hexUtils.hash(deployBytes); | ||||
|             const expectedAddress = hexUtils.slice( | ||||
|                 hexUtils.toHex(ethjs.sha3(hexUtils.concat('0xFF', deployer.address, salt, initCodeHash))), | ||||
|                 hexUtils.hash(hexUtils.concat('0xFF', deployer.address, salt, initCodeHash)), | ||||
|                 12, | ||||
|             ); | ||||
|  | ||||
| @@ -94,7 +93,7 @@ blockchainTests.resets('PermissionlessTransformerDeployer', env => { | ||||
|             const targetAddress = await deployer.deploy(deployBytes, salt).callAsync({ from: sender }); | ||||
|             await deployer.deploy(deployBytes, salt).awaitTransactionSuccessAsync({ from: sender }); | ||||
|             expect(hexUtils.toHex(await deployer.toInitCodeHash(targetAddress).callAsync())).to.eq( | ||||
|                 hexUtils.toHex(ethjs.sha3(deployBytes)), | ||||
|                 hexUtils.hash(deployBytes), | ||||
|             ); | ||||
|         }); | ||||
|     }); | ||||
|   | ||||
| @@ -125,6 +125,7 @@ export * from '../test/generated-wrappers/test_mint_token_erc20_transformer'; | ||||
| export * from '../test/generated-wrappers/test_mintable_erc20_token'; | ||||
| export * from '../test/generated-wrappers/test_mooniswap'; | ||||
| export * from '../test/generated-wrappers/test_native_orders_feature'; | ||||
| export * from '../test/generated-wrappers/test_order_signer_registry_with_contract_wallet'; | ||||
| export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_suicidal'; | ||||
| export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_transformer'; | ||||
| export * from '../test/generated-wrappers/test_rfq_origin_registration'; | ||||
|   | ||||
| @@ -156,6 +156,7 @@ | ||||
|         "test/generated-artifacts/TestMintableERC20Token.json", | ||||
|         "test/generated-artifacts/TestMooniswap.json", | ||||
|         "test/generated-artifacts/TestNativeOrdersFeature.json", | ||||
|         "test/generated-artifacts/TestOrderSignerRegistryWithContractWallet.json", | ||||
|         "test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json", | ||||
|         "test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json", | ||||
|         "test/generated-artifacts/TestRfqOriginRegistration.json", | ||||
|   | ||||
| @@ -53,6 +53,8 @@ illustrates how events are emitted when trading through the Exchange Proxy. | ||||
| +-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ | ||||
| | `RfqOrderOriginsAllowed`_     | Emitted when a tx.origin is added/removed for RFQ, via `registerAllowedRfqOrigins <./functions.html#registerallowedrfqorigins>`_                          | ExchangeProxy       | | ||||
| +-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ | ||||
| | `OrderSignerRegistered`_      | Emitted when an order signer is added/removed for a maker, via `registerAllowedOrderSigner <./functions.html#registerallowedordersigner>`_                | ExchangeProxy       | | ||||
| +-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ | ||||
| | `TransformedERC20`_           | Emitted when an `ERC20 Transformation <../advanced/erc20_transformations.html>`_ completes.                                                               | ExchangeProxy       | | ||||
| +-------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ | ||||
| | `TransformerDeployerUpdated`_ | Emitted when the Transformer Deployer is upgraded.                                                                                                        | ExchangeProxy       | | ||||
| @@ -227,7 +229,7 @@ PairCancelledLimitOrders | ||||
|     ); | ||||
|  | ||||
| PairCancelledRfqOrders | ||||
| ------------------------ | ||||
| ---------------------- | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
| @@ -311,6 +313,21 @@ RfqOrderOriginsAllowed | ||||
|         bool allowed | ||||
|     ); | ||||
|  | ||||
| OrderSignerRegistered | ||||
| ------------------------- | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev Emitted when new order signers are registered | ||||
|     /// @param maker The maker address that is registering a designated signer. | ||||
|     /// @param signer The address that will sign on behalf of maker. | ||||
|     /// @param allowed Indicates whether the address should be allowed. | ||||
|     event OrderSignerRegistered( | ||||
|         address maker, | ||||
|         address signer, | ||||
|         bool allowed | ||||
|     ); | ||||
|  | ||||
|  | ||||
| TransformedERC20 | ||||
| ---------------- | ||||
|   | ||||
| @@ -4,54 +4,69 @@ Basic Functionality | ||||
|  | ||||
| Below is a catalog of basic Exchange functionality. For more advanced usage, like meta-transactions and dex aggregation, see the Advanced section. | ||||
|  | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | **Limit Orders**                | **Overview**                                                             | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `fillLimitOrder`_               | Fills a Limit Order up to the amount requested.                          | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `fillOrKillLimitOrder`_         | Fills exactly the amount requested or reverts.                           | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `cancelLimitOrder`_             | Cancels an order so that it can no longer be filled.                     | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `batchCancelLimitOrders`_       | A batch call to `cancelLimitOrder`.                                      | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `cancelPairLimitOrders`_        | Cancels Limit orders in a specific market pair.                          | | ||||
| |                                 | Ex: Cancel all Limit Orders selling WETH for USDC.                       | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `batchCancelPairLimitOrders`_   | A batch call to `cancelPairLimitOrders`.                                 | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `getLimitOrderInfo`_            | Returns the state of a given order.                                      | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `getLimitOrderHash`_            | Returns the EIP-712 hash for an order.                                   | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | **RFQ Orders**                  | **Overview**                                                             | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `fillRfqOrder`_                 | These are analogous to the above LimitOrder functions.                   | | ||||
| +---------------------------------+                                                                          | | ||||
| | `fillOrKillRfqOrder`_           |                                                                          | | ||||
| +---------------------------------+                                                                          | | ||||
| | `cancelRfqOrder`_               |                                                                          | | ||||
| +---------------------------------+                                                                          | | ||||
| | `batchCancelRfqOrders`_         |                                                                          | | ||||
| +---------------------------------+                                                                          | | ||||
| | `cancelPairRfqOrders`_          |                                                                          | | ||||
| +---------------------------------+                                                                          | | ||||
| | `batchCancelPairRfqOrders`_     |                                                                          | | ||||
| +---------------------------------+                                                                          | | ||||
| | `getRfqOrderInfo`_              |                                                                          | | ||||
| +---------------------------------+                                                                          | | ||||
| | `getRfqOrderHash`_              |                                                                          | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `registerAllowedRfqOrigins`_    | Register tx.origin addresses that are allowed to fill an RFQ order.      | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | **Protocol Fees**               | **Overview**                                                             | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `getProtocolFeeMultiplier`_     | Takers of limit orders pay a protocol fee of `Multiplier * tx.gasprice`. | | ||||
| |                                 | This returns the `Multiplier`.                                           | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| | `transferProtocolFeesForPools`_ | Transfers protocol fees from escrow to the 0x Staking System.            | | ||||
| |                                 | This should be called near the end of each epoch.                        | | ||||
| +---------------------------------+--------------------------------------------------------------------------+ | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | **Limit Orders**                        | **Overview**                                                             | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `fillLimitOrder`_                       | Fills a Limit Order up to the amount requested.                          | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `fillOrKillLimitOrder`_                 | Fills exactly the amount requested or reverts.                           | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `cancelLimitOrder`_                     | Cancels an order so that it can no longer be filled.                     | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `batchCancelLimitOrders`_               | A batch call to `cancelLimitOrder`.                                      | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `cancelPairLimitOrders`_                | Cancels Limit orders in a specific market pair.                          | | ||||
| |                                         | Ex: Cancel all Limit Orders selling WETH for USDC.                       | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `cancelPairLimitOrdersWithSigner`_      | Same functionality to ``cancelPairLimitOrders`` but called by a          | | ||||
| |                                         | registered order signer instead of the maker itself.                     | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `batchCancelPairLimitOrders`_           | A batch call to `cancelPairLimitOrders`.                                 | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `batchCancelPairLimitOrdersWithSigner`_ | Same functionality to ``cancelPairLimitOrders`` but called by a          | | ||||
| |                                         | registered order signer instead of the maker itself.                     | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `getLimitOrderInfo`_                    | Returns the state of a given order.                                      | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `getLimitOrderHash`_                    | Returns the EIP-712 hash for an order.                                   | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | **RFQ Orders**                          | **Overview**                                                             | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `fillRfqOrder`_                         | These are analogous to the above LimitOrder functions.                   | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `fillOrKillRfqOrder`_                   |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `cancelRfqOrder`_                       |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `batchCancelRfqOrders`_                 |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `cancelPairRfqOrders`_                  |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `cancelPairRfqOrdersWithSigner`_        |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `batchCancelPairRfqOrders`_             |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `batchCancelPairRfqOrdersWithSigner`_   |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `getRfqOrderInfo`_                      |                                                                          | | ||||
| +-----------------------------------------+                                                                          | | ||||
| | `getRfqOrderHash`_                      |                                                                          | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `registerAllowedRfqOrigins`_            | Register tx.origin addresses that are allowed to fill an RFQ order.      | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `registerAllowedOrderSigner`_           | Register addresses that can sign orders on behalf of ``msg.sender``.     | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `isValidOrderSigner`_                   | Returns whether a given address is allowed to sign orders for a given    | | ||||
| |                                         | maker address.                                                           | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | **Protocol Fees**                       | **Overview**                                                             | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `getProtocolFeeMultiplier`_             | Takers of limit orders pay a protocol fee of `Multiplier * tx.gasprice`. | | ||||
| |                                         | This returns the `Multiplier`.                                           | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
| | `transferProtocolFeesForPools`_         | Transfers protocol fees from escrow to the 0x Staking System.            | | ||||
| |                                         | This should be called near the end of each epoch.                        | | ||||
| +-----------------------------------------+--------------------------------------------------------------------------+ | ||||
|  | ||||
|  | ||||
| Limit Orders | ||||
| @@ -131,7 +146,7 @@ This function cancels a single limit order created by the caller: | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event if the cancellation is successful. The call will revert if ``msg.sender != order.maker``. | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event if the cancellation is successful. The call will revert if ``msg.sender != order.maker`` or ``!isValidOrderSigner(maker, msg.sender)``. | ||||
|  | ||||
| batchCancelLimitOrders | ||||
| ---------------------- | ||||
| @@ -146,7 +161,7 @@ This function cancels multiple limit orders created by the caller: | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event for each order it cancels. The call will revert if ``msg.sender != order.maker`` for any of the orders. | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event for each order it cancels. The call will revert if ``msg.sender != order.maker`` or ``!isValidOrderSigner(maker, msg.sender)`` for any of the orders. | ||||
|  | ||||
| cancelPairLimitOrders | ||||
| --------------------- | ||||
| @@ -162,10 +177,32 @@ This function cancels all limit orders created by the caller with with a maker a | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits a `PairCancelledLimitOrders <../basics/events.html#paircancelledlimitorders>`_ event, or reverts in one of the following scenarios: | ||||
| This function emits a `PairCancelledLimitOrders <../basics/events.html#paircancelledlimitorders>`_ event, or reverts if the ``salt`` parameter is ≤ to a previous ``salt``. | ||||
|  | ||||
| - ``msg.sender != order.maker`` | ||||
| - The ``salt`` parameter is ≤ to a previous ``salt``. | ||||
| cancelPairLimitOrdersWithSigner | ||||
| ------------------------------- | ||||
|  | ||||
| Same functionality as ``cancelPairLimitOrders`` but ``msg.sender`` is a registered order signer instead of the maker itself. | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function cancelPairLimitOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| Reverts if ``!isValidOrderSigner(maker, msg.sender)``. | ||||
|  | ||||
| batchCancelPairLimitOrders | ||||
| -------------------------- | ||||
| @@ -183,6 +220,31 @@ This function performs multiple ``cancelPairLimitOrders()`` at once. Each respec | ||||
|  | ||||
| This function emits a `PairCancelledLimitOrders <../basics/events.html#paircancelledlimitorders>`_ event for each market pair it cancels. It reverts if any of the individual cancellations revert. | ||||
|  | ||||
| batchCancelPairLimitOrdersWithSigner | ||||
| ------------------------------------ | ||||
|  | ||||
| Same functionality as ``batchCancelPairLimitOrders`` but ``msg.sender`` is a registered order signer instead of the maker itself. | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev Cancel all limit orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerTokens The maker tokens. | ||||
|     /// @param takerTokens The taker tokens. | ||||
|     /// @param minValidSalts The new minimum valid salts. | ||||
|     function batchCancelPairLimitOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06[] memory makerTokens, | ||||
|         IERC20TokenV06[] memory takerTokens, | ||||
|         uint256[] memory minValidSalts | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| Reverts if ``!isValidOrderSigner(maker, msg.sender)``. | ||||
|  | ||||
| getLimitOrderInfo | ||||
| ----------------- | ||||
|  | ||||
| @@ -369,7 +431,7 @@ Similar to limit orders, RFQ orders can be cancelled on-chain through a variety | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event if the cancellation is successful. The call will revert if ``msg.sender != order.maker``. | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event if the cancellation is successful. The call will revert if ``msg.sender != order.maker`` or ``!isValidOrderSigner(maker, msg.sender)``. | ||||
|  | ||||
| batchCancelRfqOrders | ||||
| -------------------- | ||||
| @@ -384,7 +446,7 @@ This function cancels multiple RFQ orders created by the caller: | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event for each order it cancels. The call will revert if ``msg.sender != order.maker`` for any of the orders. | ||||
| This function emits an `OrderCancelled <../basics/events.html#ordercancelled>`_ event for each order it cancels. The call will revert if ``msg.sender != order.maker`` or ``!isValidOrderSigner(maker, msg.sender)`` for any orders for any of the orders. | ||||
|  | ||||
| cancelPairRfqOrders | ||||
| ------------------- | ||||
| @@ -400,10 +462,32 @@ This function cancels all RFQ orders created by the caller with with a maker and | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits a `PairCancelledRfqOrders <../basics/events.html#paircancelledrfqorders>`_ event, or reverts in one of the following scenarios: | ||||
| This function emits a `PairCancelledRfqOrders <../basics/events.html#paircancelledrfqorders>`_ event, or reverts if the ``salt`` parameter is ≤ to a previous ``salt``. | ||||
|  | ||||
| - ``msg.sender != order.maker`` | ||||
| - The ``salt`` parameter is ≤ to a previous ``salt``. | ||||
| cancelPairRfqOrdersWithSigner | ||||
| ----------------------------- | ||||
|  | ||||
| Same functionality as ``cancelPairRfqOrders`` but ``msg.sender`` is a registered order signer instead of the maker itself. | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pair with a salt less | ||||
|     ///      than the value provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerToken The maker token. | ||||
|     /// @param takerToken The taker token. | ||||
|     /// @param minValidSalt The new minimum valid salt. | ||||
|     function cancelPairRfqOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06 makerToken, | ||||
|         IERC20TokenV06 takerToken, | ||||
|         uint256 minValidSalt | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| Reverts if ``!isValidOrderSigner(maker, msg.sender)``. | ||||
|  | ||||
| batchCancelPairRfqOrders | ||||
| ------------------------ | ||||
| @@ -421,6 +505,31 @@ batchCancelPairRfqOrders | ||||
|  | ||||
| This function emits a `PairCancelledRfqOrders <../basics/events.html#paircancelledrfqorders>`_  event for each market pair it cancels. It reverts if any of the individual cancellations revert. | ||||
|  | ||||
| batchCancelPairRfqOrdersWithSigner | ||||
| ---------------------------------- | ||||
|  | ||||
| Same functionality as ``batchCancelPairRfqOrders`` but ``msg.sender`` is a registered order signer instead of the maker itself. | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev Cancel all RFQ orders for a given maker and pairs with salts less | ||||
|     ///      than the values provided. The caller must be a signer registered to the maker. | ||||
|     ///      Subsequent calls to this function with the same maker and pair require the | ||||
|     ///      new salt to be >= the old salt. | ||||
|     /// @param maker The maker for which to cancel. | ||||
|     /// @param makerTokens The maker tokens. | ||||
|     /// @param takerTokens The taker tokens. | ||||
|     /// @param minValidSalts The new minimum valid salts. | ||||
|     function batchCancelPairRfqOrdersWithSigner( | ||||
|         address maker, | ||||
|         IERC20TokenV06[] memory makerTokens, | ||||
|         IERC20TokenV06[] memory takerTokens, | ||||
|         uint256[] memory minValidSalts | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| Reverts if ``!isValidOrderSigner(maker, msg.sender)``. | ||||
|  | ||||
| getRfqOrderInfo | ||||
| --------------- | ||||
|  | ||||
| @@ -549,6 +658,47 @@ Looking at the 2nd use case, a maker can register valid tx origins using this fu | ||||
|  | ||||
| This function emits a `RfqOrderOriginsAllowed <../basics/events.html#rfqorderoriginsallowed>`_ event. | ||||
|  | ||||
| registerAllowedOrderSigner | ||||
| -------------------------- | ||||
|  | ||||
| Calls to fill functions require a signature provided by the maker. In cases where the signer can't be the maker itself (e.g. a contract wallet), the maker can delegate signing to another address. | ||||
|  | ||||
| To register a new delegated order signer, the maker can call ``registerAllowedOrderSigner`` with ``allowed == true``. | ||||
|  | ||||
| To revoke permission to a signer, the maker can call ``registerAllowedOrderSigner`` with ``allowed == false``. | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev Register a signer who can sign on behalf of msg.sender | ||||
|     ///      This allows one to sign on behalf of a contract that calls this function | ||||
|     /// @param signer The address from which you plan to generate signatures | ||||
|     /// @param allowed True to register, false to unregister. | ||||
|     function registerAllowedOrderSigner( | ||||
|         address signer, | ||||
|         bool allowed | ||||
|     ) | ||||
|         external; | ||||
|  | ||||
| This function emits an `OrderSignerRegistered <../basics/events.html#ordersignerregistered>`_ event. | ||||
|  | ||||
| isValidOrderSigner | ||||
| ------------------ | ||||
|  | ||||
| Returns whether the ``signer`` is allowed to sign orders on behalf of the ``maker``. | ||||
|  | ||||
| .. code-block:: solidity | ||||
|  | ||||
|     /// @dev checks if a given address is registered to sign on behalf of a maker address | ||||
|     /// @param maker The maker address encoded in an order (can be a contract) | ||||
|     /// @param signer The address that is providing a signature | ||||
|     function isValidOrderSigner( | ||||
|         address maker, | ||||
|         address signer | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bool isAllowed); | ||||
|  | ||||
|  | ||||
| Protocol Fees | ||||
| ============= | ||||
|   | ||||
| @@ -92,7 +92,7 @@ The ``RFQOrder`` struct has the following fields: | ||||
| How To Sign | ||||
| ============== | ||||
|  | ||||
| Both Limit & RFQ orders must be signed by the `maker`. This signature is needed to fill an order, see `Basic Functionality <./functions.html>`_. | ||||
| Both Limit & RFQ orders must be signed by the `maker` or a registered order signer (`registerAllowedOrderSigner <./functions.html#registerallowedrfqorigins>`_). This signature is needed to fill an order, see `Basic Functionality <./functions.html>`_. | ||||
|  | ||||
| The protocol accepts signatures defined by the following struct: | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ Protocol Fees | ||||
|  | ||||
| An ETH protocol fee is paid by the Taker each time a `Limit Order <./orders.html#limit-orders>`_ is `filled <./functions.html>`_. | ||||
| The fee is proportional to the gas cost of filling an order and scales linearly with gas price. The cost is currently ``70k * tx.gasprice``.  | ||||
| Every 10 days, these fees are aggregated and distributed to the makers as a liquidity reward: the reward is proportional to the maker's collected fees and staked ZRX relative to other makers. | ||||
| At the end of every Staking Epoch, these fees are aggregated and distributed to the makers as a liquidity reward: the reward is proportional to the maker's collected fees and staked ZRX relative to other makers. | ||||
| To learn more about protocol fees and liquidity incentives, see the `Official Spec <https://github.com/0xProject/0x-protocol-specification/blob/master/staking/staking-specification.md>`_. | ||||
|  | ||||
| .. note:: | ||||
|   | ||||
| @@ -66,7 +66,7 @@ | ||||
|         "ignoreDependencyVersionsForPackage": "contract-wrappers" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "@0x/monorepo-scripts": "^3.1.1", | ||||
|         "@0x/monorepo-scripts": "^3.1.6", | ||||
|         "@0x-lerna-fork/lerna": "3.16.10", | ||||
|         "@0xproject/npm-cli-login": "^0.0.11", | ||||
|         "async-child-process": "^1.1.1", | ||||
|   | ||||
| @@ -1,4 +1,89 @@ | ||||
| [ | ||||
|     { | ||||
|         "version": "6.9.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Temporarily remove PancakeV2 and BakerySwap from VIP" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619830995 | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.9.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Remove conflicting Kyber reserve", | ||||
|                 "pr": 216 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619825976 | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.8.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Prune paths which cannot improve the best path", | ||||
|                 "pr": 183 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Use FastABI for Sampler ABI encoding and decoding", | ||||
|                 "pr": 183 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619596077 | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.7.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Support PancakeSwap V2", | ||||
|                 "pr": 211 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1619481586 | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.6.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Fixing Positive Slippage logic to not force the EP route", | ||||
|                 "pr": 209 | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.6.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Support `Ropsten` network", | ||||
|                 "pr": 203 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap), Saddle BTC pool, Curve gas schedule", | ||||
|                 "pr": 208 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1618592834 | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.5.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Apply slippage to bridge orders in consumer", | ||||
|                 "pr": 198 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1618433771 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1618314654, | ||||
|         "version": "6.5.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1618259868, | ||||
|         "version": "6.5.1", | ||||
|   | ||||
| @@ -5,6 +5,40 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v6.9.1 - _May 1, 2021_ | ||||
|  | ||||
|     * Temporarily remove PancakeV2 and BakerySwap from VIP | ||||
|  | ||||
| ## v6.9.0 - _April 30, 2021_ | ||||
|  | ||||
|     * Remove conflicting Kyber reserve (#216) | ||||
|  | ||||
| ## v6.8.0 - _April 28, 2021_ | ||||
|  | ||||
|     * Prune paths which cannot improve the best path (#183) | ||||
|     * Use FastABI for Sampler ABI encoding and decoding (#183) | ||||
|  | ||||
| ## v6.7.0 - _April 26, 2021_ | ||||
|  | ||||
|     * Support PancakeSwap V2 (#211) | ||||
|  | ||||
| ## v6.6.1 - _Invalid date_ | ||||
|  | ||||
|     * Fixing Positive Slippage logic to not force the EP route (#209) | ||||
|  | ||||
| ## v6.6.0 - _April 16, 2021_ | ||||
|  | ||||
|     * Support `Ropsten` network (#203) | ||||
|     * BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap), Saddle BTC pool, Curve gas schedule (#208) | ||||
|  | ||||
| ## v6.5.3 - _April 14, 2021_ | ||||
|  | ||||
|     * Apply slippage to bridge orders in consumer (#198) | ||||
|  | ||||
| ## v6.5.2 - _April 13, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v6.5.1 - _April 12, 2021_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/asset-swapper", | ||||
|     "version": "6.5.1", | ||||
|     "version": "6.9.1", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -57,20 +57,20 @@ | ||||
|         "registry": "git@github.com:0xProject/gitpkg-registry.git" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.21", | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/assert": "^3.0.26", | ||||
|         "@0x/base-contract": "^6.4.0", | ||||
|         "@0x/contract-addresses": "^6.0.0", | ||||
|         "@0x/contract-wrappers": "^13.15.0", | ||||
|         "@0x/contracts-erc20": "^3.3.6", | ||||
|         "@0x/contracts-zero-ex": "^0.21.1", | ||||
|         "@0x/dev-utils": "^4.2.1", | ||||
|         "@0x/json-schemas": "^5.4.1", | ||||
|         "@0x/protocol-utils": "^1.4.1", | ||||
|         "@0x/contract-wrappers": "^13.16.0", | ||||
|         "@0x/contracts-erc20": "^3.3.7", | ||||
|         "@0x/contracts-zero-ex": "^0.22.3", | ||||
|         "@0x/dev-utils": "^4.2.6", | ||||
|         "@0x/json-schemas": "^6.1.2", | ||||
|         "@0x/protocol-utils": "^1.5.1", | ||||
|         "@0x/quote-server": "^5.0.0", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/typescript-typings": "^5.1.6", | ||||
|         "@0x/utils": "^6.2.0", | ||||
|         "@0x/web3-wrapper": "^7.4.1", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@0x/typescript-typings": "^5.2.0", | ||||
|         "@0x/utils": "^6.4.2", | ||||
|         "@0x/web3-wrapper": "^7.5.2", | ||||
|         "@balancer-labs/sor": "0.3.2", | ||||
|         "@bancor/sdk": "0.2.9", | ||||
|         "@ethersproject/abi": "^5.0.1", | ||||
| @@ -82,26 +82,27 @@ | ||||
|         "axios-mock-adapter": "^1.19.0", | ||||
|         "cream-sor": "^0.3.3", | ||||
|         "decimal.js": "^10.2.0", | ||||
|         "ethereum-types": "^3.4.0", | ||||
|         "ethereumjs-util": "^5.1.1", | ||||
|         "ethereum-types": "^3.5.0", | ||||
|         "ethereumjs-util": "^7.0.10", | ||||
|         "fast-abi": "^0.0.2", | ||||
|         "heartbeats": "^5.0.1", | ||||
|         "lodash": "^4.17.11" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "@0x/base-contract": "^6.2.18", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.9", | ||||
|         "@0x/contracts-exchange": "^3.2.28", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.32", | ||||
|         "@0x/contracts-test-utils": "^5.3.24", | ||||
|         "@0x/contracts-utils": "^4.7.6", | ||||
|         "@0x/abi-gen": "^5.6.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.10", | ||||
|         "@0x/contracts-exchange": "^3.2.29", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.28", | ||||
|         "@0x/contracts-gen": "^2.0.37", | ||||
|         "@0x/contracts-test-utils": "^5.3.25", | ||||
|         "@0x/contracts-utils": "^4.7.7", | ||||
|         "@0x/mesh-rpc-client": "^9.4.2", | ||||
|         "@0x/migrations": "^8.0.1", | ||||
|         "@0x/sol-compiler": "^4.6.1", | ||||
|         "@0x/subproviders": "^6.4.1", | ||||
|         "@0x/migrations": "^8.0.5", | ||||
|         "@0x/sol-compiler": "^4.7.2", | ||||
|         "@0x/subproviders": "^6.5.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.3", | ||||
|         "@0x/types": "^3.3.1", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
|         "@0x/types": "^3.3.3", | ||||
|         "@types/lodash": "4.14.104", | ||||
|         "@types/mocha": "^5.2.7", | ||||
|         "@types/node": "12.12.54", | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import { | ||||
|     CalldataInfo, | ||||
|     ExchangeProxyContractOpts, | ||||
|     MarketBuySwapQuote, | ||||
|     MarketOperation, | ||||
|     MarketSellSwapQuote, | ||||
|     SwapQuote, | ||||
|     SwapQuoteConsumerBase, | ||||
| @@ -43,6 +44,7 @@ import { | ||||
|     LiquidityProviderFillData, | ||||
|     MooniswapFillData, | ||||
|     OptimizedMarketBridgeOrder, | ||||
|     OptimizedMarketOrder, | ||||
|     UniswapV2FillData, | ||||
| } from '../utils/market_operation_utils/types'; | ||||
|  | ||||
| @@ -63,7 +65,18 @@ import { | ||||
| // tslint:disable-next-line:custom-no-magic-numbers | ||||
| const MAX_UINT256 = new BigNumber(2).pow(256).minus(1); | ||||
| const { NULL_ADDRESS, NULL_BYTES, ZERO_AMOUNT } = constants; | ||||
| const PANCAKE_SWAP_FORKS = [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.BakerySwap, ERC20BridgeSource.SushiSwap]; | ||||
|  | ||||
| // use the same order in IPancakeSwapFeature.sol | ||||
| const PANCAKE_SWAP_FORKS = [ | ||||
|     ERC20BridgeSource.PancakeSwap, | ||||
|     ERC20BridgeSource.PancakeSwapV2, | ||||
|     ERC20BridgeSource.BakerySwap, | ||||
|     ERC20BridgeSource.SushiSwap, | ||||
|     ERC20BridgeSource.ApeSwap, | ||||
|     ERC20BridgeSource.CafeSwap, | ||||
|     ERC20BridgeSource.CheeseSwap, | ||||
|     ERC20BridgeSource.JulSwap, | ||||
| ]; | ||||
| const DUMMY_WETH_CONTRACT = new WETH9Contract(NULL_ADDRESS, { | ||||
|     sendAsync(): void { | ||||
|         return; | ||||
| @@ -136,7 +149,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|         const buyToken = quote.makerToken; | ||||
|  | ||||
|         // Take the bounds from the worst case | ||||
|         const sellAmount = quote.worstCaseQuoteInfo.totalTakerAmount; | ||||
|         const sellAmount = BigNumber.max( | ||||
|             quote.bestCaseQuoteInfo.totalTakerAmount, | ||||
|             quote.worstCaseQuoteInfo.totalTakerAmount, | ||||
|         ); | ||||
|         let minBuyAmount = quote.worstCaseQuoteInfo.makerAmount; | ||||
|         let ethAmount = quote.worstCaseQuoteInfo.protocolFeeInWeiAmount; | ||||
|  | ||||
| @@ -144,13 +160,15 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             ethAmount = ethAmount.plus(sellAmount); | ||||
|         } | ||||
|  | ||||
|         const slippedOrders = slipNonNativeOrders(quote); | ||||
|  | ||||
|         // VIP routes. | ||||
|         if ( | ||||
|             this.chainId === ChainId.Mainnet && | ||||
|             isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap]) | ||||
|         ) { | ||||
|             const source = quote.orders[0].source; | ||||
|             const fillData = (quote.orders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; | ||||
|             const source = slippedOrders[0].source; | ||||
|             const fillData = (slippedOrders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; | ||||
|             return { | ||||
|                 calldataHexString: this._exchangeProxy | ||||
|                     .sellToUniswap( | ||||
| @@ -179,12 +197,18 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             this.chainId === ChainId.BSC && | ||||
|             isDirectSwapCompatible(quote, optsWithDefaults, [ | ||||
|                 ERC20BridgeSource.PancakeSwap, | ||||
|                 ERC20BridgeSource.BakerySwap, | ||||
|                 // Temporarily removed until latest PancakeSwap VIP has been deployed | ||||
|                 // ERC20BridgeSource.PancakeSwapV2, | ||||
|                 // ERC20BridgeSource.BakerySwap, | ||||
|                 ERC20BridgeSource.SushiSwap, | ||||
|                 ERC20BridgeSource.ApeSwap, | ||||
|                 ERC20BridgeSource.CafeSwap, | ||||
|                 ERC20BridgeSource.CheeseSwap, | ||||
|                 ERC20BridgeSource.JulSwap, | ||||
|             ]) | ||||
|         ) { | ||||
|             const source = quote.orders[0].source; | ||||
|             const fillData = (quote.orders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; | ||||
|             const source = slippedOrders[0].source; | ||||
|             const fillData = (slippedOrders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; | ||||
|             return { | ||||
|                 calldataHexString: this._exchangeProxy | ||||
|                     .sellToPancakeSwap( | ||||
| @@ -213,7 +237,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             this.chainId === ChainId.Mainnet && | ||||
|             isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.LiquidityProvider]) | ||||
|         ) { | ||||
|             const fillData = (quote.orders[0] as OptimizedMarketBridgeOrder<LiquidityProviderFillData>).fillData; | ||||
|             const fillData = (slippedOrders[0] as OptimizedMarketBridgeOrder<LiquidityProviderFillData>).fillData; | ||||
|             const target = fillData.poolAddress; | ||||
|             return { | ||||
|                 calldataHexString: this._exchangeProxy | ||||
| @@ -238,7 +262,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             this.chainId === ChainId.Mainnet && | ||||
|             isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve, ERC20BridgeSource.Swerve]) | ||||
|         ) { | ||||
|             const fillData = quote.orders[0].fills[0].fillData as CurveFillData; | ||||
|             const fillData = slippedOrders[0].fills[0].fillData as CurveFillData; | ||||
|             return { | ||||
|                 calldataHexString: this._exchangeProxy | ||||
|                     .sellToLiquidityProvider( | ||||
| @@ -267,7 +291,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             this.chainId === ChainId.Mainnet && | ||||
|             isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Mooniswap]) | ||||
|         ) { | ||||
|             const fillData = quote.orders[0].fills[0].fillData as MooniswapFillData; | ||||
|             const fillData = slippedOrders[0].fills[0].fillData as MooniswapFillData; | ||||
|             return { | ||||
|                 calldataHexString: this._exchangeProxy | ||||
|                     .sellToLiquidityProvider( | ||||
| @@ -289,7 +313,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|  | ||||
|         if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) { | ||||
|             return { | ||||
|                 calldataHexString: this._encodeMultiplexBatchFillCalldata(quote), | ||||
|                 calldataHexString: this._encodeMultiplexBatchFillCalldata({ ...quote, orders: slippedOrders }), | ||||
|                 ethAmount, | ||||
|                 toAddress: this._exchangeProxy.address, | ||||
|                 allowanceTarget: this._exchangeProxy.address, | ||||
| @@ -298,7 +322,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|         } | ||||
|         if (this.chainId === ChainId.Mainnet && isMultiplexMultiHopFillCompatible(quote, optsWithDefaults)) { | ||||
|             return { | ||||
|                 calldataHexString: this._encodeMultiplexMultiHopFillCalldata(quote, optsWithDefaults), | ||||
|                 calldataHexString: this._encodeMultiplexMultiHopFillCalldata( | ||||
|                     { ...quote, orders: slippedOrders }, | ||||
|                     optsWithDefaults, | ||||
|                 ), | ||||
|                 ethAmount, | ||||
|                 toAddress: this._exchangeProxy.address, | ||||
|                 allowanceTarget: this._exchangeProxy.address, | ||||
| @@ -321,10 +348,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|  | ||||
|         // If it's two hop we have an intermediate token this is needed to encode the individual FQT | ||||
|         // and we also want to ensure no dust amount is left in the flash wallet | ||||
|         const intermediateToken = quote.isTwoHop ? quote.orders[0].makerToken : NULL_ADDRESS; | ||||
|         const intermediateToken = quote.isTwoHop ? slippedOrders[0].makerToken : NULL_ADDRESS; | ||||
|         // This transformer will fill the quote. | ||||
|         if (quote.isTwoHop) { | ||||
|             const [firstHopOrder, secondHopOrder] = quote.orders; | ||||
|             const [firstHopOrder, secondHopOrder] = slippedOrders; | ||||
|             transforms.push({ | ||||
|                 deploymentNonce: this.transformerNonces.fillQuoteTransformer, | ||||
|                 data: encodeFillQuoteTransformerData({ | ||||
| @@ -349,14 +376,13 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             }); | ||||
|         } else { | ||||
|             const fillAmount = isBuyQuote(quote) ? quote.makerTokenFillAmount : quote.takerTokenFillAmount; | ||||
|  | ||||
|             transforms.push({ | ||||
|                 deploymentNonce: this.transformerNonces.fillQuoteTransformer, | ||||
|                 data: encodeFillQuoteTransformerData({ | ||||
|                     side: isBuyQuote(quote) ? FillQuoteTransformerSide.Buy : FillQuoteTransformerSide.Sell, | ||||
|                     sellToken, | ||||
|                     buyToken, | ||||
|                     ...getFQTTransformerDataFromOptimizedOrders(quote.orders), | ||||
|                     ...getFQTTransformerDataFromOptimizedOrders(slippedOrders), | ||||
|                     refundReceiver: refundReceiver || NULL_ADDRESS, | ||||
|                     fillAmount: !isBuyQuote(quote) && shouldSellEntireBalance ? MAX_UINT256 : fillAmount, | ||||
|                 }), | ||||
| @@ -598,3 +624,38 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase { | ||||
|             .getABIEncodedTransactionData(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function slipNonNativeOrders(quote: MarketSellSwapQuote | MarketBuySwapQuote): OptimizedMarketOrder[] { | ||||
|     const slippage = getMaxQuoteSlippageRate(quote); | ||||
|     if (!slippage) { | ||||
|         return quote.orders; | ||||
|     } | ||||
|     return quote.orders.map(o => { | ||||
|         if (o.source === ERC20BridgeSource.Native) { | ||||
|             return o; | ||||
|         } | ||||
|         return { | ||||
|             ...o, | ||||
|             ...(quote.type === MarketOperation.Sell | ||||
|                 ? { makerAmount: o.makerAmount.times(1 - slippage).integerValue(BigNumber.ROUND_DOWN) } | ||||
|                 : { takerAmount: o.takerAmount.times(1 + slippage).integerValue(BigNumber.ROUND_UP) }), | ||||
|         }; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function getMaxQuoteSlippageRate(quote: MarketBuySwapQuote | MarketSellSwapQuote): number { | ||||
|     if (quote.type === MarketOperation.Buy) { | ||||
|         // (worstCaseTaker - bestCaseTaker) / bestCaseTaker | ||||
|         // where worstCaseTaker >= bestCaseTaker | ||||
|         return quote.worstCaseQuoteInfo.takerAmount | ||||
|             .minus(quote.bestCaseQuoteInfo.takerAmount) | ||||
|             .div(quote.bestCaseQuoteInfo.takerAmount) | ||||
|             .toNumber(); | ||||
|     } | ||||
|     // (bestCaseMaker - worstCaseMaker) / bestCaseMaker | ||||
|     // where bestCaseMaker >= worstCaseMaker | ||||
|     return quote.bestCaseQuoteInfo.makerAmount | ||||
|         .minus(quote.worstCaseQuoteInfo.makerAmount) | ||||
|         .div(quote.bestCaseQuoteInfo.makerAmount) | ||||
|         .toNumber(); | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { FillQuoteTransformerData, FillQuoteTransformerOrderType } from '@0x/protocol-utils'; | ||||
|  | ||||
| import { AffiliateFeeType, ExchangeProxyContractOpts, MarketBuySwapQuote, MarketOperation, SwapQuote } from '../types'; | ||||
| import { ExchangeProxyContractOpts, MarketBuySwapQuote, MarketOperation, SwapQuote } from '../types'; | ||||
| import { | ||||
|     createBridgeDataForBridgeOrder, | ||||
|     getErc20BridgeSourceToBridgeSource, | ||||
| @@ -70,6 +70,7 @@ export function isMultiplexMultiHopFillCompatible(quote: SwapQuote, opts: Exchan | ||||
| /** | ||||
|  * Returns true iff a quote can be filled via a VIP feature. | ||||
|  */ | ||||
|  | ||||
| export function isDirectSwapCompatible( | ||||
|     quote: SwapQuote, | ||||
|     opts: ExchangeProxyContractOpts, | ||||
| @@ -163,10 +164,6 @@ export function requiresTransformERC20(opts: ExchangeProxyContractOpts): boolean | ||||
|     if (!opts.affiliateFee.buyTokenFeeAmount.eq(0) || !opts.affiliateFee.sellTokenFeeAmount.eq(0)) { | ||||
|         return true; | ||||
|     } | ||||
|     // Has a positive slippage fee. | ||||
|     if (opts.affiliateFee.feeType === AffiliateFeeType.PositiveSlippageFee) { | ||||
|         return true; | ||||
|     } | ||||
|     // VIP does not support selling the entire balance | ||||
|     if (opts.shouldSellEntireBalance) { | ||||
|         return true; | ||||
|   | ||||
| @@ -2,7 +2,8 @@ import { ChainId, getContractAddressesForChainOrThrow } from '@0x/contract-addre | ||||
| import { FillQuoteTransformerOrderType, LimitOrder } from '@0x/protocol-utils'; | ||||
| import { BigNumber, providerUtils } from '@0x/utils'; | ||||
| import Axios, { AxiosInstance } from 'axios'; | ||||
| import { BlockParamLiteral, SupportedProvider, ZeroExProvider } from 'ethereum-types'; | ||||
| import { BlockParamLiteral, MethodAbi, SupportedProvider, ZeroExProvider } from 'ethereum-types'; | ||||
| import { FastABI } from 'fast-abi'; | ||||
| import { Agent as HttpAgent } from 'http'; | ||||
| import { Agent as HttpsAgent } from 'https'; | ||||
| import * as _ from 'lodash'; | ||||
| @@ -122,12 +123,19 @@ export class SwapQuoter { | ||||
|             { block: BlockParamLiteral.Latest, overrides: defaultCodeOverrides }, | ||||
|             options.samplerOverrides, | ||||
|         ); | ||||
|         const fastAbi = new FastABI(ERC20BridgeSamplerContract.ABI() as MethodAbi[]); | ||||
|         const samplerContract = new ERC20BridgeSamplerContract( | ||||
|             this._contractAddresses.erc20BridgeSampler, | ||||
|             this.provider, | ||||
|             { | ||||
|                 gas: samplerGasLimit, | ||||
|             }, | ||||
|             {}, | ||||
|             undefined, | ||||
|             { | ||||
|                 encodeInput: (fnName: string, values: any) => fastAbi.encodeInput(fnName, values), | ||||
|                 decodeOutput: (fnName: string, data: string) => fastAbi.decodeOutput(fnName, data), | ||||
|             }, | ||||
|         ); | ||||
|  | ||||
|         this._marketOperationUtils = new MarketOperationUtils( | ||||
| @@ -591,9 +599,10 @@ function calculateTwoHopQuoteInfo( | ||||
|                 : secondHopOrder.makerAmount, | ||||
|             takerAmount: MarketOperation.Sell | ||||
|                 ? firstHopOrder.takerAmount | ||||
|                 : // tslint:disable-next-line: binary-expression-operand-order | ||||
|                   firstHopOrder.takerAmount.times(1 + slippage).integerValue(), | ||||
|             totalTakerAmount: firstHopOrder.takerAmount, | ||||
|                 : firstHopOrder.takerAmount.times(1 + slippage).integerValue(), | ||||
|             totalTakerAmount: MarketOperation.Sell | ||||
|                 ? firstHopOrder.takerAmount | ||||
|                 : firstHopOrder.takerAmount.times(1 + slippage).integerValue(), | ||||
|             feeTakerTokenAmount: constants.ZERO_AMOUNT, | ||||
|             protocolFeeInWeiAmount: constants.ZERO_AMOUNT, | ||||
|             gas, | ||||
|   | ||||
| @@ -2,12 +2,17 @@ import { ChainId } from '@0x/contract-addresses'; | ||||
| import { BigNumber, NULL_BYTES } from '@0x/utils'; | ||||
|  | ||||
| import { | ||||
|     APESWAP_ROUTER_BY_CHAIN_ID, | ||||
|     BAKERYSWAP_ROUTER_BY_CHAIN_ID, | ||||
|     BELT_BSC_INFOS, | ||||
|     CAFESWAP_ROUTER_BY_CHAIN_ID, | ||||
|     CHEESESWAP_ROUTER_BY_CHAIN_ID, | ||||
|     COMPONENT_POOLS_BY_CHAIN_ID, | ||||
|     CRYPTO_COM_ROUTER_BY_CHAIN_ID, | ||||
|     CURVE_MAINNET_INFOS, | ||||
|     ELLIPSIS_BSC_INFOS, | ||||
|     JULSWAP_ROUTER_BY_CHAIN_ID, | ||||
|     KYBER_BANNED_RESERVES, | ||||
|     KYBER_BRIDGED_LIQUIDITY_PREFIX, | ||||
|     KYBER_DMM_ROUTER_BY_CHAIN_ID, | ||||
|     MAX_DODOV2_POOLS_QUERIED, | ||||
| @@ -15,6 +20,7 @@ import { | ||||
|     NERVE_BSC_INFOS, | ||||
|     NULL_ADDRESS, | ||||
|     PANCAKESWAP_ROUTER_BY_CHAIN_ID, | ||||
|     PANCAKESWAPV2_ROUTER_BY_CHAIN_ID, | ||||
|     SADDLE_MAINNET_INFOS, | ||||
|     SHELL_POOLS_BY_CHAIN_ID, | ||||
|     SMOOTHY_BSC_INFOS, | ||||
| @@ -31,7 +37,11 @@ import { CurveInfo, ERC20BridgeSource } from './types'; | ||||
|  * @param reserveId Kyber reserveId | ||||
|  */ | ||||
| export function isAllowedKyberReserveId(reserveId: string): boolean { | ||||
|     return reserveId !== NULL_BYTES && !reserveId.startsWith(KYBER_BRIDGED_LIQUIDITY_PREFIX); | ||||
|     return ( | ||||
|         reserveId !== NULL_BYTES && | ||||
|         !reserveId.startsWith(KYBER_BRIDGED_LIQUIDITY_PREFIX) && | ||||
|         !KYBER_BANNED_RESERVES.includes(reserveId) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| // tslint:disable-next-line: completed-docs ban-types | ||||
| @@ -252,8 +262,13 @@ export function uniswapV2LikeRouterAddress( | ||||
|         | ERC20BridgeSource.SushiSwap | ||||
|         | ERC20BridgeSource.CryptoCom | ||||
|         | ERC20BridgeSource.PancakeSwap | ||||
|         | ERC20BridgeSource.PancakeSwapV2 | ||||
|         | ERC20BridgeSource.BakerySwap | ||||
|         | ERC20BridgeSource.KyberDmm, | ||||
|         | ERC20BridgeSource.KyberDmm | ||||
|         | ERC20BridgeSource.ApeSwap | ||||
|         | ERC20BridgeSource.CafeSwap | ||||
|         | ERC20BridgeSource.CheeseSwap | ||||
|         | ERC20BridgeSource.JulSwap, | ||||
| ): string { | ||||
|     switch (source) { | ||||
|         case ERC20BridgeSource.UniswapV2: | ||||
| @@ -264,10 +279,20 @@ export function uniswapV2LikeRouterAddress( | ||||
|             return CRYPTO_COM_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.PancakeSwap: | ||||
|             return PANCAKESWAP_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.PancakeSwapV2: | ||||
|             return PANCAKESWAPV2_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.BakerySwap: | ||||
|             return BAKERYSWAP_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.KyberDmm: | ||||
|             return KYBER_DMM_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.ApeSwap: | ||||
|             return APESWAP_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.CafeSwap: | ||||
|             return CAFESWAP_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.CheeseSwap: | ||||
|             return CHEESESWAP_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         case ERC20BridgeSource.JulSwap: | ||||
|             return JULSWAP_ROUTER_BY_CHAIN_ID[chainId]; | ||||
|         default: | ||||
|             throw new Error(`Unknown UniswapV2 like source ${source}`); | ||||
|     } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { ChainId } from '@0x/contract-addresses'; | ||||
| import { ChainId, getContractAddressesForChainOrThrow } from '@0x/contract-addresses'; | ||||
| import { FillQuoteTransformerOrderType } from '@0x/protocol-utils'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import { formatBytes32String } from '@ethersproject/strings'; | ||||
| @@ -87,7 +87,13 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.Component, | ||||
|             ERC20BridgeSource.Saddle, | ||||
|         ]), | ||||
|         [ChainId.Ropsten]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
|         [ChainId.Ropsten]: new SourceFilters([ | ||||
|             ERC20BridgeSource.Kyber, | ||||
|             ERC20BridgeSource.Native, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
|             ERC20BridgeSource.Uniswap, | ||||
|             ERC20BridgeSource.UniswapV2, | ||||
|         ]), | ||||
|         [ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
|         [ChainId.Kovan]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
|         [ChainId.Ganache]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
| @@ -101,8 +107,13 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.Nerve, | ||||
|             ERC20BridgeSource.PancakeSwap, | ||||
|             ERC20BridgeSource.PancakeSwapV2, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
|             ERC20BridgeSource.Smoothy, | ||||
|             ERC20BridgeSource.ApeSwap, | ||||
|             ERC20BridgeSource.CafeSwap, | ||||
|             ERC20BridgeSource.CheeseSwap, | ||||
|             ERC20BridgeSource.JulSwap, | ||||
|         ]), | ||||
|     }, | ||||
|  | ||||
| @@ -142,7 +153,13 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.Component, | ||||
|             ERC20BridgeSource.Saddle, | ||||
|         ]), | ||||
|         [ChainId.Ropsten]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
|         [ChainId.Ropsten]: new SourceFilters([ | ||||
|             ERC20BridgeSource.Kyber, | ||||
|             ERC20BridgeSource.Native, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
|             ERC20BridgeSource.Uniswap, | ||||
|             ERC20BridgeSource.UniswapV2, | ||||
|         ]), | ||||
|         [ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
|         [ChainId.Kovan]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
|         [ChainId.Ganache]: new SourceFilters([ERC20BridgeSource.Native]), | ||||
| @@ -156,8 +173,13 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.Nerve, | ||||
|             ERC20BridgeSource.PancakeSwap, | ||||
|             ERC20BridgeSource.PancakeSwapV2, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
|             ERC20BridgeSource.Smoothy, | ||||
|             ERC20BridgeSource.ApeSwap, | ||||
|             ERC20BridgeSource.CafeSwap, | ||||
|             ERC20BridgeSource.CheeseSwap, | ||||
|             ERC20BridgeSource.JulSwap, | ||||
|         ]), | ||||
|     }, | ||||
|     new SourceFilters([]), | ||||
| @@ -175,6 +197,7 @@ export const FEE_QUOTE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]> | ||||
|     { | ||||
|         [ChainId.Mainnet]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap], | ||||
|         [ChainId.BSC]: [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.SushiSwap], | ||||
|         [ChainId.Ropsten]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap], | ||||
|     }, | ||||
|     [], | ||||
| ); | ||||
| @@ -369,6 +392,7 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>( | ||||
|             '0x2170ed0880ac9a755fd29b2688956bd959f933f8', // ETH | ||||
|             '0x55d398326f99059ff775485246999027b3197955', // BUSD-T | ||||
|         ], | ||||
|         [ChainId.Ropsten]: [getContractAddressesForChainOrThrow(ChainId.Ropsten).etherToken], | ||||
|     }, | ||||
|     [], | ||||
| ); | ||||
| @@ -397,8 +421,12 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj | ||||
|  | ||||
| export const NATIVE_FEE_TOKEN_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Mainnet]: MAINNET_TOKENS.WETH, | ||||
|         [ChainId.BSC]: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c', // WBNB | ||||
|         [ChainId.Mainnet]: getContractAddressesForChainOrThrow(ChainId.Mainnet).etherToken, | ||||
|         [ChainId.BSC]: getContractAddressesForChainOrThrow(ChainId.BSC).etherToken, | ||||
|         [ChainId.Ganache]: getContractAddressesForChainOrThrow(ChainId.Ganache).etherToken, | ||||
|         [ChainId.Ropsten]: getContractAddressesForChainOrThrow(ChainId.Ropsten).etherToken, | ||||
|         [ChainId.Rinkeby]: getContractAddressesForChainOrThrow(ChainId.Rinkeby).etherToken, | ||||
|         [ChainId.Kovan]: getContractAddressesForChainOrThrow(ChainId.Kovan).etherToken, | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
| @@ -458,147 +486,147 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
|     [CURVE_POOLS.compound]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC], | ||||
|         pool: CURVE_POOLS.compound, | ||||
|         gasSchedule: 597e3, | ||||
|         gasSchedule: 587e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.PAX]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.PAX], | ||||
|         pool: CURVE_POOLS.PAX, | ||||
|         gasSchedule: 752e3, | ||||
|         gasSchedule: 742e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.sUSD]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.sUSD], | ||||
|         pool: CURVE_POOLS.sUSD, | ||||
|         gasSchedule: 312e3, | ||||
|         gasSchedule: 302e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.renBTC]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.WBTC], | ||||
|         pool: CURVE_POOLS.renBTC, | ||||
|         gasSchedule: 181e3, | ||||
|         gasSchedule: 171e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.sBTC]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.sBTC], | ||||
|         pool: CURVE_POOLS.sBTC, | ||||
|         gasSchedule: 337e3, | ||||
|         gasSchedule: 327e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.HBTC]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.hBTC, MAINNET_TOKENS.WBTC], | ||||
|         pool: CURVE_POOLS.HBTC, | ||||
|         gasSchedule: 220e3, | ||||
|         gasSchedule: 210e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.TRI]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT], | ||||
|         pool: CURVE_POOLS.TRI, | ||||
|         gasSchedule: 186e3, | ||||
|         gasSchedule: 176e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.GUSD]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.GUSD, | ||||
|         pool: CURVE_POOLS.GUSD, | ||||
|         gasSchedule: 421e3, | ||||
|         gasSchedule: 411e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.HUSD]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.HUSD, | ||||
|         pool: CURVE_POOLS.HUSD, | ||||
|         gasSchedule: 406e3, | ||||
|         gasSchedule: 396e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.USDN]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.USDN, | ||||
|         pool: CURVE_POOLS.USDN, | ||||
|         gasSchedule: 408e3, | ||||
|         gasSchedule: 398e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.mUSD]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.mUSD, | ||||
|         pool: CURVE_POOLS.mUSD, | ||||
|         gasSchedule: 395e3, | ||||
|         gasSchedule: 385e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.dUSD]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.dUSD, | ||||
|         pool: CURVE_POOLS.dUSD, | ||||
|         gasSchedule: 381e3, | ||||
|         gasSchedule: 371e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.tBTC]: createCurveMetaTriBtcPool({ | ||||
|         token: MAINNET_TOKENS.tBTC, | ||||
|         pool: CURVE_POOLS.tBTC, | ||||
|         gasSchedule: 492e3, | ||||
|         gasSchedule: 482e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.pBTC]: createCurveMetaTriBtcPool({ | ||||
|         token: MAINNET_TOKENS.pBTC, | ||||
|         pool: CURVE_POOLS.pBTC, | ||||
|         gasSchedule: 513e3, | ||||
|         gasSchedule: 503e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.bBTC]: createCurveMetaTriBtcPool({ | ||||
|         token: MAINNET_TOKENS.bBTC, | ||||
|         pool: CURVE_POOLS.bBTC, | ||||
|         gasSchedule: 507e3, | ||||
|         gasSchedule: 497e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.oBTC]: createCurveMetaTriBtcPool({ | ||||
|         token: MAINNET_TOKENS.oBTC, | ||||
|         pool: CURVE_POOLS.oBTC, | ||||
|         gasSchedule: 498e3, | ||||
|         gasSchedule: 488e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.UST]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.UST, | ||||
|         pool: CURVE_POOLS.UST, | ||||
|         gasSchedule: 350e3, | ||||
|         gasSchedule: 340e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.eurs]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.EURS, MAINNET_TOKENS.sEUR], | ||||
|         pool: CURVE_POOLS.eurs, | ||||
|         gasSchedule: 330e3, | ||||
|         gasSchedule: 320e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.aave]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT], | ||||
|         pool: CURVE_POOLS.aave, | ||||
|         gasSchedule: 590e3, | ||||
|         gasSchedule: 580e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.aave]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.aDAI, MAINNET_TOKENS.aUSDC, MAINNET_TOKENS.aUSDT], | ||||
|         pool: CURVE_POOLS.aave, | ||||
|         gasSchedule: 590e3, | ||||
|         gasSchedule: 580e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.saave]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.sUSD], | ||||
|         pool: CURVE_POOLS.saave, | ||||
|         gasSchedule: 590e3, | ||||
|         gasSchedule: 580e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.saave]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.aDAI, MAINNET_TOKENS.aSUSD], | ||||
|         pool: CURVE_POOLS.saave, | ||||
|         gasSchedule: 590e3, | ||||
|         gasSchedule: 580e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.USDP]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.USDP, | ||||
|         pool: CURVE_POOLS.USDP, | ||||
|         gasSchedule: 384e3, | ||||
|         gasSchedule: 374e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.ib]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT], | ||||
|         pool: CURVE_POOLS.ib, | ||||
|         gasSchedule: 656e3, | ||||
|         gasSchedule: 646e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.link]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.LINK, MAINNET_TOKENS.sLINK], | ||||
|         pool: CURVE_POOLS.link, | ||||
|         gasSchedule: 329e3, | ||||
|         gasSchedule: 319e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.TUSD]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.TUSD, | ||||
|         pool: CURVE_POOLS.TUSD, | ||||
|         gasSchedule: 414e3, | ||||
|         gasSchedule: 404e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.STABLEx]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.STABLEx, | ||||
|         pool: CURVE_POOLS.STABLEx, | ||||
|         gasSchedule: 407e3, | ||||
|         gasSchedule: 397e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.alUSD]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.alUSD, | ||||
|         pool: CURVE_POOLS.alUSD, | ||||
|         gasSchedule: 397e3, | ||||
|         gasSchedule: 387e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.FRAX]: createCurveMetaTriPool({ | ||||
|         token: MAINNET_TOKENS.FRAX, | ||||
|         pool: CURVE_POOLS.FRAX, | ||||
|         gasSchedule: 397e3, | ||||
|         gasSchedule: 387e3, | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| @@ -606,7 +634,7 @@ export const SWERVE_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
|     [SWERVE_POOLS.y]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.TUSD], | ||||
|         pool: SWERVE_POOLS.y, | ||||
|         gasSchedule: 150e3, | ||||
|         gasSchedule: 140e3, | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| @@ -614,22 +642,22 @@ export const SNOWSWAP_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
|     [SNOWSWAP_POOLS.yUSD]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.yUSD, MAINNET_TOKENS.ybCRV], | ||||
|         pool: SNOWSWAP_POOLS.yUSD, | ||||
|         gasSchedule: 1000e3, | ||||
|         gasSchedule: 990e3, | ||||
|     }), | ||||
|     [SNOWSWAP_POOLS.yUSD]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [MAINNET_TOKENS.yCRV, MAINNET_TOKENS.bCRV], | ||||
|         pool: SNOWSWAP_POOLS.yUSD, | ||||
|         gasSchedule: 1000e3, | ||||
|         gasSchedule: 990e3, | ||||
|     }), | ||||
|     [SNOWSWAP_POOLS.yVault]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.yDAI, MAINNET_TOKENS.yUSDC, MAINNET_TOKENS.yUSDT, MAINNET_TOKENS.yTUSD], | ||||
|         pool: SNOWSWAP_POOLS.yVault, | ||||
|         gasSchedule: 1500e3, | ||||
|         gasSchedule: 1490e3, | ||||
|     }), | ||||
|     [SNOWSWAP_POOLS.eth]: createCurveExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.vETH, MAINNET_TOKENS.ankrETH, MAINNET_TOKENS.crETH], | ||||
|         pool: SNOWSWAP_POOLS.eth, | ||||
|         gasSchedule: 1000e3, | ||||
|         gasSchedule: 990e3, | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| @@ -637,7 +665,7 @@ export const BELT_BSC_INFOS: { [name: string]: CurveInfo } = { | ||||
|     [BELT_POOLS.vPool]: createCurveExchangeUnderlyingPool({ | ||||
|         tokens: [BSC_TOKENS.DAI, BSC_TOKENS.USDC, BSC_TOKENS.USDT, BSC_TOKENS.BUSD], | ||||
|         pool: BELT_POOLS.vPool, | ||||
|         gasSchedule: 4500e3, | ||||
|         gasSchedule: 4490e3, | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| @@ -645,7 +673,7 @@ export const ELLIPSIS_BSC_INFOS: { [name: string]: CurveInfo } = { | ||||
|     [ELLIPSIS_POOLS.threePool]: createCurveExchangePool({ | ||||
|         tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDC, BSC_TOKENS.USDT], | ||||
|         pool: ELLIPSIS_POOLS.threePool, | ||||
|         gasSchedule: 150e3, | ||||
|         gasSchedule: 140e3, | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| @@ -658,18 +686,17 @@ export const SADDLE_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
|         poolAddress: SADDLE_POOLS.stables, | ||||
|         tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT], | ||||
|         metaToken: undefined, | ||||
|         gasSchedule: 220e3, | ||||
|         gasSchedule: 150e3, | ||||
|     }, | ||||
|     [SADDLE_POOLS.bitcoins]: { | ||||
|         exchangeFunctionSelector: CurveFunctionSelectors.swap, | ||||
|         sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap, | ||||
|         buyQuoteFunctionSelector: CurveFunctionSelectors.None, | ||||
|         poolAddress: SADDLE_POOLS.bitcoins, | ||||
|         tokens: [MAINNET_TOKENS.tBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.sBTC], | ||||
|         metaToken: undefined, | ||||
|         gasSchedule: 150e3, | ||||
|     }, | ||||
|     // TODO:Romain having "Cannot swap more than you own" error when running simbot | ||||
|     // [SADDLE_POOLS.bitcoins]: { | ||||
|     //     exchangeFunctionSelector: CurveFunctionSelectors.swap, | ||||
|     //     sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap, | ||||
|     //     buyQuoteFunctionSelector: CurveFunctionSelectors.None, | ||||
|     //     poolAddress: SADDLE_POOLS.stables, | ||||
|     //     tokens: [MAINNET_TOKENS.tBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.sBTC], | ||||
|     //     metaToken: undefined, | ||||
|     //     gasSchedule: 220e3, | ||||
|     // }, | ||||
| }; | ||||
|  | ||||
| export const SMOOTHY_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
| @@ -689,7 +716,7 @@ export const SMOOTHY_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
|             MAINNET_TOKENS.GUSD, | ||||
|         ], | ||||
|         metaToken: undefined, | ||||
|         gasSchedule: 200e3, | ||||
|         gasSchedule: 190e3, | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| @@ -701,7 +728,7 @@ export const SMOOTHY_BSC_INFOS: { [name: string]: CurveInfo } = { | ||||
|         poolAddress: SMOOTHY_POOLS.syUSD, | ||||
|         tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.USDC, BSC_TOKENS.DAI, BSC_TOKENS.PAX, BSC_TOKENS.UST], | ||||
|         metaToken: undefined, | ||||
|         gasSchedule: 100e3, | ||||
|         gasSchedule: 90e3, | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| @@ -713,7 +740,7 @@ export const NERVE_BSC_INFOS: { [name: string]: CurveInfo } = { | ||||
|         poolAddress: NERVE_POOLS.threePool, | ||||
|         tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.USDC], | ||||
|         metaToken: undefined, | ||||
|         gasSchedule: 150e3, | ||||
|         gasSchedule: 140e3, | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| @@ -724,6 +751,7 @@ export const NERVE_BSC_INFOS: { [name: string]: CurveInfo } = { | ||||
|  * 0xbb Bridged price reserve (i.e Uniswap/Curve) | ||||
|  */ | ||||
| export const KYBER_BRIDGED_LIQUIDITY_PREFIX = '0xbb'; | ||||
| export const KYBER_BANNED_RESERVES = ['0xff4f6e65426974205175616e7400000000000000000000000000000000000000']; | ||||
| export const MAX_KYBER_RESERVES_QUERIED = 5; | ||||
| export const KYBER_CONFIG_BY_CHAIN_ID = valueByChainId<KyberSamplerOpts>( | ||||
|     { | ||||
| @@ -732,6 +760,11 @@ export const KYBER_CONFIG_BY_CHAIN_ID = valueByChainId<KyberSamplerOpts>( | ||||
|             hintHandler: '0xa1C0Fa73c39CFBcC11ec9Eb1Afc665aba9996E2C', | ||||
|             weth: MAINNET_TOKENS.WETH, | ||||
|         }, | ||||
|         [ChainId.Ropsten]: { | ||||
|             networkProxy: '0x818e6fecd516ecc3849daf6845e3ec868087b755', | ||||
|             hintHandler: '0x63f773c026093eef988e803bdd5772dd235a8e71', | ||||
|             weth: getContractAddressesForChainOrThrow(ChainId.Ropsten).etherToken, | ||||
|         }, | ||||
|     }, | ||||
|     { | ||||
|         networkProxy: NULL_ADDRESS, | ||||
| @@ -768,6 +801,7 @@ export const LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID = valueByChainId<LiquidityP | ||||
| export const UNISWAPV1_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Mainnet]: '0xc0a47dfe034b400b47bdad5fecda2621de6c4d95', | ||||
|         [ChainId.Ropsten]: '0x9c83dce8ca20e9aaf9d3efc003b2ea62abc08351', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
| @@ -775,6 +809,7 @@ export const UNISWAPV1_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
| export const UNISWAPV2_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Mainnet]: '0xf164fc0ec4e93095b804a4795bbe1e041497b92a', | ||||
|         [ChainId.Ropsten]: '0xf164fc0ec4e93095b804a4795bbe1e041497b92a', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
| @@ -783,6 +818,7 @@ export const SUSHISWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Mainnet]: '0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f', | ||||
|         [ChainId.BSC]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506', | ||||
|         [ChainId.Ropsten]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
| @@ -964,6 +1000,13 @@ export const PANCAKESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const PANCAKESWAPV2_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.BSC]: '0x10ed43c718714eb63d5aa57b78b54704e256024e', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const BAKERYSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.BSC]: '0xcde540d7eafe93ac5fe6233bee57e1270d3e330f', | ||||
| @@ -971,6 +1014,34 @@ export const BAKERYSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const APESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.BSC]: '0xc0788a3ad43d79aa53b09c2eacc313a787d1d607', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const CAFESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.BSC]: '0x933daea3a5995fb94b14a7696a5f3ffd7b1e385a', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const CHEESESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.BSC]: '0x3047799262d8d2ef41ed2a222205968bc9b0d895', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const JULSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.BSC]: '0xbd67d157502a23309db761c41965600c2ec788b2', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * Calculated gross gas cost of the underlying exchange. | ||||
|  * The cost of switching from one source to another, assuming | ||||
| @@ -990,7 +1061,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|     }, | ||||
|     [ERC20BridgeSource.Uniswap]: () => 90e3, | ||||
|     [ERC20BridgeSource.LiquidityProvider]: fillData => { | ||||
|         return (fillData as LiquidityProviderFillData).gasCost; | ||||
|         return (fillData as LiquidityProviderFillData).gasCost || 100e3; | ||||
|     }, | ||||
|     [ERC20BridgeSource.Eth2Dai]: () => 400e3, | ||||
|     [ERC20BridgeSource.Kyber]: () => 450e3, | ||||
| @@ -1101,6 +1172,15 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.PancakeSwapV2]: (fillData?: FillData) => { | ||||
|         // TODO: Different base cost if to/from ETH. | ||||
|         let gas = 90e3; | ||||
|         const path = (fillData as UniswapV2FillData).tokenAddressPath; | ||||
|         if (path.length > 2) { | ||||
|             gas += (path.length - 2) * 60e3; // +60k for each hop. | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.BakerySwap]: (fillData?: FillData) => { | ||||
|         // TODO: Different base cost if to/from ETH. | ||||
|         let gas = 90e3; | ||||
| @@ -1110,6 +1190,42 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.ApeSwap]: (fillData?: FillData) => { | ||||
|         // TODO: Different base cost if to/from ETH. | ||||
|         let gas = 90e3; | ||||
|         const path = (fillData as UniswapV2FillData).tokenAddressPath; | ||||
|         if (path.length > 2) { | ||||
|             gas += (path.length - 2) * 60e3; // +60k for each hop. | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.CafeSwap]: (fillData?: FillData) => { | ||||
|         // TODO: Different base cost if to/from ETH. | ||||
|         let gas = 90e3; | ||||
|         const path = (fillData as UniswapV2FillData).tokenAddressPath; | ||||
|         if (path.length > 2) { | ||||
|             gas += (path.length - 2) * 60e3; // +60k for each hop. | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.CheeseSwap]: (fillData?: FillData) => { | ||||
|         // TODO: Different base cost if to/from ETH. | ||||
|         let gas = 90e3; | ||||
|         const path = (fillData as UniswapV2FillData).tokenAddressPath; | ||||
|         if (path.length > 2) { | ||||
|             gas += (path.length - 2) * 60e3; // +60k for each hop. | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.JulSwap]: (fillData?: FillData) => { | ||||
|         // TODO: Different base cost if to/from ETH. | ||||
|         let gas = 90e3; | ||||
|         const path = (fillData as UniswapV2FillData).tokenAddressPath; | ||||
|         if (path.length > 2) { | ||||
|             gas += (path.length - 2) * 60e3; // +60k for each hop. | ||||
|         } | ||||
|         return gas; | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE }; | ||||
|   | ||||
| @@ -152,7 +152,7 @@ function dexSamplesToFills( | ||||
|         const { source, fillData } = sample; | ||||
|         const input = sample.input.minus(prevSample ? prevSample.input : 0); | ||||
|         const output = sample.output.minus(prevSample ? prevSample.output : 0); | ||||
|         const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData); | ||||
|         const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0; | ||||
|         let penalty = ZERO_AMOUNT; | ||||
|         if (i === 0) { | ||||
|             // Only the first fill in a DEX path incurs a penalty. | ||||
|   | ||||
| @@ -120,6 +120,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Linkswap'); | ||||
|         case ERC20BridgeSource.PancakeSwap: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'PancakeSwap'); | ||||
|         case ERC20BridgeSource.PancakeSwapV2: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'PancakeSwapV2'); | ||||
|         case ERC20BridgeSource.BakerySwap: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'BakerySwap'); | ||||
|         case ERC20BridgeSource.Nerve: | ||||
| @@ -134,6 +136,14 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s | ||||
|             return encodeBridgeSourceId(BridgeProtocol.Curve, 'Smoothy'); | ||||
|         case ERC20BridgeSource.Saddle: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Saddle'); | ||||
|         case ERC20BridgeSource.ApeSwap: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'ApeSwap'); | ||||
|         case ERC20BridgeSource.CafeSwap: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'CafeSwap'); | ||||
|         case ERC20BridgeSource.CheeseSwap: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'CheeseSwap'); | ||||
|         case ERC20BridgeSource.JulSwap: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'JulSwap'); | ||||
|         default: | ||||
|             throw new Error(AggregationError.NoBridgeForSource); | ||||
|     } | ||||
| @@ -185,8 +195,13 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder | ||||
|         case ERC20BridgeSource.CryptoCom: | ||||
|         case ERC20BridgeSource.Linkswap: | ||||
|         case ERC20BridgeSource.PancakeSwap: | ||||
|         case ERC20BridgeSource.PancakeSwapV2: | ||||
|         case ERC20BridgeSource.BakerySwap: | ||||
|         case ERC20BridgeSource.KyberDmm: | ||||
|         case ERC20BridgeSource.ApeSwap: | ||||
|         case ERC20BridgeSource.CafeSwap: | ||||
|         case ERC20BridgeSource.CheeseSwap: | ||||
|         case ERC20BridgeSource.JulSwap: | ||||
|             const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; | ||||
|             bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]); | ||||
|             break; | ||||
| @@ -320,6 +335,14 @@ export const BRIDGE_ENCODERS: { | ||||
|     [ERC20BridgeSource.CryptoCom]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.Linkswap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.KyberDmm]: routerAddressPathEncoder, | ||||
|     // BSC | ||||
|     [ERC20BridgeSource.PancakeSwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.PancakeSwapV2]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.BakerySwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.ApeSwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.CafeSwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.CheeseSwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.JulSwap]: routerAddressPathEncoder, | ||||
|     // Generic pools | ||||
|     [ERC20BridgeSource.Shell]: poolEncoder, | ||||
|     [ERC20BridgeSource.Component]: poolEncoder, | ||||
| @@ -331,9 +354,6 @@ export const BRIDGE_ENCODERS: { | ||||
|     [ERC20BridgeSource.Uniswap]: poolEncoder, | ||||
|     // Custom integrations | ||||
|     [ERC20BridgeSource.MakerPsm]: makerPsmEncoder, | ||||
|     // BSC | ||||
|     [ERC20BridgeSource.PancakeSwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.BakerySwap]: routerAddressPathEncoder, | ||||
| }; | ||||
|  | ||||
| function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] { | ||||
|   | ||||
| @@ -152,6 +152,17 @@ export class Path { | ||||
|         return getRate(this.side, input, output); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the best possible rate this path can offer, given the fills. | ||||
|      */ | ||||
|     public bestRate(): BigNumber { | ||||
|         const best = this.fills.reduce((prevRate, curr) => { | ||||
|             const currRate = getRate(this.side, curr.input, curr.output); | ||||
|             return prevRate.isLessThan(currRate) ? currRate : prevRate; | ||||
|         }, new BigNumber(0)); | ||||
|         return best; | ||||
|     } | ||||
|  | ||||
|     public adjustedSlippage(maxRate: BigNumber): number { | ||||
|         if (maxRate.eq(0)) { | ||||
|             return 0; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import * as _ from 'lodash'; | ||||
| import { MarketOperation } from '../../types'; | ||||
|  | ||||
| import { DEFAULT_PATH_PENALTY_OPTS, Path, PathPenaltyOpts } from './path'; | ||||
| import { Fill } from './types'; | ||||
| import { ERC20BridgeSource, Fill } from './types'; | ||||
|  | ||||
| // tslint:disable: prefer-for-of custom-no-magic-numbers completed-docs no-bitwise | ||||
|  | ||||
| @@ -22,12 +22,13 @@ export async function findOptimalPathAsync( | ||||
|     opts: PathPenaltyOpts = DEFAULT_PATH_PENALTY_OPTS, | ||||
| ): Promise<Path | undefined> { | ||||
|     // Sort fill arrays by descending adjusted completed rate. | ||||
|     const sortedPaths = fillsToSortedPaths(fills, side, targetInput, opts); | ||||
|     // Remove any paths which cannot impact the optimal path | ||||
|     const sortedPaths = reducePaths(fillsToSortedPaths(fills, side, targetInput, opts), side); | ||||
|     if (sortedPaths.length === 0) { | ||||
|         return undefined; | ||||
|     } | ||||
|     const rates = rateBySourcePathId(sortedPaths); | ||||
|     let optimalPath = sortedPaths[0]; | ||||
|     const rates = rateBySourcePathId(side, fills, targetInput); | ||||
|     for (const [i, path] of sortedPaths.slice(1).entries()) { | ||||
|         optimalPath = mixPaths(side, optimalPath, path, targetInput, runLimit * RUN_LIMIT_DECAY_FACTOR ** i, rates); | ||||
|         // Yield to event loop. | ||||
| @@ -44,10 +45,47 @@ export function fillsToSortedPaths( | ||||
|     opts: PathPenaltyOpts, | ||||
| ): Path[] { | ||||
|     const paths = fills.map(singleSourceFills => Path.create(side, singleSourceFills, targetInput, opts)); | ||||
|     const sortedPaths = paths.sort((a, b) => b.adjustedCompleteRate().comparedTo(a.adjustedCompleteRate())); | ||||
|     const sortedPaths = paths.sort((a, b) => { | ||||
|         const aRate = a.adjustedCompleteRate(); | ||||
|         const bRate = b.adjustedCompleteRate(); | ||||
|         // There is a case where the adjusted completed rate isn't sufficient for the desired amount | ||||
|         // resulting in a NaN div by 0 (output) | ||||
|         if (bRate.isNaN()) { | ||||
|             return -1; | ||||
|         } | ||||
|         if (aRate.isNaN()) { | ||||
|             return 1; | ||||
|         } | ||||
|         return bRate.comparedTo(aRate); | ||||
|     }); | ||||
|     return sortedPaths; | ||||
| } | ||||
|  | ||||
| // Remove paths which have no impact on the optimal path | ||||
| export function reducePaths(sortedPaths: Path[], side: MarketOperation): Path[] { | ||||
|     // Any path which has a min rate that is less than the best adjusted completed rate has no chance of improving | ||||
|     // the overall route. | ||||
|     const bestNonNativeCompletePath = sortedPaths.filter( | ||||
|         p => p.isComplete() && p.fills[0].source !== ERC20BridgeSource.Native, | ||||
|     )[0]; | ||||
|  | ||||
|     // If there is no complete path then just go ahead with the sorted paths | ||||
|     // I.e if the token only exists on sources which cannot sell to infinity | ||||
|     // or buys where X is greater than all the tokens available in the pools | ||||
|     if (!bestNonNativeCompletePath) { | ||||
|         return sortedPaths; | ||||
|     } | ||||
|     const bestNonNativeCompletePathAdjustedRate = bestNonNativeCompletePath.adjustedCompleteRate(); | ||||
|     if (!bestNonNativeCompletePathAdjustedRate.isGreaterThan(0)) { | ||||
|         return sortedPaths; | ||||
|     } | ||||
|  | ||||
|     const filteredPaths = sortedPaths.filter(p => | ||||
|         p.bestRate().isGreaterThanOrEqualTo(bestNonNativeCompletePathAdjustedRate), | ||||
|     ); | ||||
|     return filteredPaths; | ||||
| } | ||||
|  | ||||
| function mixPaths( | ||||
|     side: MarketOperation, | ||||
|     pathA: Path, | ||||
| @@ -98,17 +136,6 @@ function mixPaths( | ||||
|     return bestPath; | ||||
| } | ||||
|  | ||||
| function rateBySourcePathId( | ||||
|     side: MarketOperation, | ||||
|     fills: Fill[][], | ||||
|     targetInput: BigNumber, | ||||
| ): { [id: string]: BigNumber } { | ||||
|     const flattenedFills = _.flatten(fills); | ||||
|     const sourcePathIds = flattenedFills.filter(f => f.index === 0).map(f => f.sourcePathId); | ||||
|     return Object.assign( | ||||
|         {}, | ||||
|         ...sourcePathIds.map(s => ({ | ||||
|             [s]: Path.create(side, flattenedFills.filter(f => f.sourcePathId === s), targetInput).adjustedRate(), | ||||
|         })), | ||||
|     ); | ||||
| function rateBySourcePathId(paths: Path[]): { [id: string]: BigNumber } { | ||||
|     return _.fromPairs(paths.map(p => [p.fills[0].sourcePathId, p.adjustedRate()])); | ||||
| } | ||||
|   | ||||
| @@ -141,6 +141,13 @@ export class SamplerOperations { | ||||
|         orders: SignedNativeOrder[], | ||||
|         exchangeAddress: string, | ||||
|     ): BatchedOperation<BigNumber[]> { | ||||
|         // Skip checking empty or invalid orders on-chain, returning a constant | ||||
|         if (orders.length === 0) { | ||||
|             return SamplerOperations.constant<BigNumber[]>([]); | ||||
|         } | ||||
|         if (orders.length === 1 && orders[0].order.maker === NULL_ADDRESS) { | ||||
|             return SamplerOperations.constant<BigNumber[]>([ZERO_AMOUNT]); | ||||
|         } | ||||
|         return new SamplerContractOperation({ | ||||
|             source: ERC20BridgeSource.Native, | ||||
|             contract: this._samplerContract, | ||||
| @@ -154,6 +161,13 @@ export class SamplerOperations { | ||||
|         orders: SignedNativeOrder[], | ||||
|         exchangeAddress: string, | ||||
|     ): BatchedOperation<BigNumber[]> { | ||||
|         // Skip checking empty or invalid orders on-chain, returning a constant | ||||
|         if (orders.length === 0) { | ||||
|             return SamplerOperations.constant<BigNumber[]>([]); | ||||
|         } | ||||
|         if (orders.length === 1 && orders[0].order.maker === NULL_ADDRESS) { | ||||
|             return SamplerOperations.constant<BigNumber[]>([ZERO_AMOUNT]); | ||||
|         } | ||||
|         return new SamplerContractOperation({ | ||||
|             source: ERC20BridgeSource.Native, | ||||
|             contract: this._samplerContract, | ||||
| @@ -1086,8 +1100,13 @@ export class SamplerOperations { | ||||
|                         case ERC20BridgeSource.SushiSwap: | ||||
|                         case ERC20BridgeSource.CryptoCom: | ||||
|                         case ERC20BridgeSource.PancakeSwap: | ||||
|                         case ERC20BridgeSource.PancakeSwapV2: | ||||
|                         case ERC20BridgeSource.BakerySwap: | ||||
|                         case ERC20BridgeSource.KyberDmm: | ||||
|                         case ERC20BridgeSource.ApeSwap: | ||||
|                         case ERC20BridgeSource.CafeSwap: | ||||
|                         case ERC20BridgeSource.CheeseSwap: | ||||
|                         case ERC20BridgeSource.JulSwap: | ||||
|                             const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); | ||||
|                             if (!isValidAddress(uniLikeRouter)) { | ||||
|                                 return []; | ||||
| @@ -1295,8 +1314,13 @@ export class SamplerOperations { | ||||
|                         case ERC20BridgeSource.SushiSwap: | ||||
|                         case ERC20BridgeSource.CryptoCom: | ||||
|                         case ERC20BridgeSource.PancakeSwap: | ||||
|                         case ERC20BridgeSource.PancakeSwapV2: | ||||
|                         case ERC20BridgeSource.BakerySwap: | ||||
|                         case ERC20BridgeSource.KyberDmm: | ||||
|                         case ERC20BridgeSource.ApeSwap: | ||||
|                         case ERC20BridgeSource.CafeSwap: | ||||
|                         case ERC20BridgeSource.CheeseSwap: | ||||
|                         case ERC20BridgeSource.JulSwap: | ||||
|                             const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); | ||||
|                             if (!isValidAddress(uniLikeRouter)) { | ||||
|                                 return []; | ||||
|   | ||||
| @@ -65,10 +65,15 @@ export enum ERC20BridgeSource { | ||||
|     Saddle = 'Saddle', | ||||
|     // BSC only | ||||
|     PancakeSwap = 'PancakeSwap', | ||||
|     PancakeSwapV2 = 'PancakeSwap_V2', | ||||
|     BakerySwap = 'BakerySwap', | ||||
|     Nerve = 'Nerve', | ||||
|     Belt = 'Belt', | ||||
|     Ellipsis = 'Ellipsis', | ||||
|     ApeSwap = 'ApeSwap', | ||||
|     CafeSwap = 'CafeSwap', | ||||
|     CheeseSwap = 'CheeseSwap', | ||||
|     JulSwap = 'JulSwap', | ||||
| } | ||||
|  | ||||
| // tslint:disable: enum-naming | ||||
|   | ||||
| @@ -83,7 +83,7 @@ export class QuoteRequestor { | ||||
|         sellTokenAddress: string, // taker token | ||||
|         assetFillAmount: BigNumber, | ||||
|         comparisonPrice?: BigNumber, | ||||
|         isLastLook: boolean = false, | ||||
|         isLastLook?: boolean | undefined, | ||||
|     ): TakerRequestQueryParams { | ||||
|         const { buyAmountBaseUnits, sellAmountBaseUnits } = | ||||
|             marketOperation === MarketOperation.Buy | ||||
| @@ -111,9 +111,11 @@ export class QuoteRequestor { | ||||
|             buyTokenAddress, | ||||
|             sellTokenAddress, | ||||
|             comparisonPrice: comparisonPrice === undefined ? undefined : comparisonPrice.toString(), | ||||
|             isLastLook: isLastLook.toString(), | ||||
|             protocolVersion: '4', | ||||
|         }; | ||||
|         if (isLastLook) { | ||||
|             requestParamsWithBigNumbers.isLastLook = isLastLook.toString(); | ||||
|         } | ||||
|  | ||||
|         // convert BigNumbers to strings | ||||
|         // so they are digestible by axios | ||||
|   | ||||
| @@ -129,11 +129,10 @@ export function simulateWorstCaseFill(quoteInfo: QuoteFillInfo): QuoteFillResult | ||||
|     }; | ||||
|     // Adjust the output by 1-slippage for the worst case if it is a sell | ||||
|     // Adjust the output by 1+slippage for the worst case if it is a buy | ||||
|     const outputMultiplier = | ||||
|     result.output = | ||||
|         quoteInfo.side === MarketOperation.Sell | ||||
|             ? new BigNumber(1).minus(opts.slippage) | ||||
|             : new BigNumber(1).plus(opts.slippage); | ||||
|     result.output = result.output.times(outputMultiplier).integerValue(); | ||||
|             ? result.output.times(1 - opts.slippage).integerValue(BigNumber.ROUND_DOWN) | ||||
|             : result.output.times(1 + opts.slippage).integerValue(BigNumber.ROUND_UP); | ||||
|     return fromIntermediateQuoteFillResult(result, quoteInfo); | ||||
| } | ||||
|  | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user