Compare commits
	
		
			31 Commits
		
	
	
		
			@0x/contra
			...
			protocol@9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9754e12d82 | ||
| 
						 | 
					d72ebed246 | ||
| 
						 | 
					587fc71058 | ||
| 
						 | 
					7d34e09a12 | ||
| 
						 | 
					7d15baad0f | ||
| 
						 | 
					1e6476ada7 | ||
| 
						 | 
					1d6ca5f6b5 | ||
| 
						 | 
					fb249f02fc | ||
| 
						 | 
					fdf04ef275 | ||
| 
						 | 
					b0f5f634f2 | ||
| 
						 | 
					6ee0108565 | ||
| 
						 | 
					c73097e688 | ||
| 
						 | 
					a2d42b07b5 | ||
| 
						 | 
					f9a794af93 | ||
| 
						 | 
					a2643674ca | ||
| 
						 | 
					c00ce9daac | ||
| 
						 | 
					c68b5d7844 | ||
| 
						 | 
					09ed106d4c | ||
| 
						 | 
					a6b92fc658 | ||
| 
						 | 
					4be4a1a30b | ||
| 
						 | 
					9bede5d331 | ||
| 
						 | 
					b50d4aee6d | ||
| 
						 | 
					55bc367bd6 | ||
| 
						 | 
					7a59b7eafe | ||
| 
						 | 
					9e59d41e44 | ||
| 
						 | 
					475e6c7bca | ||
| 
						 | 
					dbc5a5293e | ||
| 
						 | 
					f4bd2bd0d8 | ||
| 
						 | 
					f1782a83ba | ||
| 
						 | 
					cbade0d558 | ||
| 
						 | 
					fe0c26387c | 
@@ -1,25 +1,25 @@
 | 
			
		||||
version: 2
 | 
			
		||||
version: 2.1
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
    build:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        resource_class: large
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        environment:
 | 
			
		||||
            CONTRACTS_COMMIT_HASH: '9ed05f5'
 | 
			
		||||
            NODE_OPTIONS: '--max-old-space-size=6442'
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - checkout
 | 
			
		||||
            - run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
 | 
			
		||||
            - run:
 | 
			
		||||
                  name: install-yarn
 | 
			
		||||
                  command: npm install --force --global yarn@1.17.0
 | 
			
		||||
                  command: npm install --force --global yarn@1.22.0
 | 
			
		||||
            - run:
 | 
			
		||||
                  name: yarn
 | 
			
		||||
                  command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
 | 
			
		||||
            - setup_remote_docker
 | 
			
		||||
            - run: yarn build:ci
 | 
			
		||||
            - run: yarn build:ts
 | 
			
		||||
            - run: yarn build:ci || yarn build:ci || yarn build:ci
 | 
			
		||||
            - run: yarn build:ts || yarn build:ts || yarn build:ts
 | 
			
		||||
            - save_cache:
 | 
			
		||||
                  key: repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
                  paths:
 | 
			
		||||
@@ -31,57 +31,59 @@ jobs:
 | 
			
		||||
    test-exchange-ganache:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contracts-exchange
 | 
			
		||||
            - run: yarn wsrun -p @0x/contracts-exchange -m --serial -c test:circleci
 | 
			
		||||
    test-integrations-ganache:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contracts-integrations
 | 
			
		||||
            - run: yarn wsrun -p @0x/contracts-integrations -m --serial -c test:circleci
 | 
			
		||||
    test-contracts-staking-ganache:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contracts-staking
 | 
			
		||||
            - run: yarn wsrun -p @0x/contracts-staking -m --serial -c test:circleci
 | 
			
		||||
    test-contracts-extra-ganache:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contracts-exchange-forwarder @0x/contracts-coordinator
 | 
			
		||||
            - run: yarn wsrun -p @0x/contracts-exchange-forwarder -p @0x/contracts-coordinator -m --serial -c test:circleci
 | 
			
		||||
    test-contracts-rest-ganache:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contracts-multisig @0x/contracts-utils @0x/contracts-exchange-libs @0x/contracts-erc20 @0x/contracts-erc721 @0x/contracts-erc1155 @0x/contracts-asset-proxy @0x/contracts-broker @0x/contracts-zero-ex
 | 
			
		||||
            - run: yarn wsrun -p @0x/contracts-multisig -p @0x/contracts-utils -p @0x/contracts-exchange-libs -p  @0x/contracts-erc20 -p @0x/contracts-erc721 -p @0x/contracts-erc1155 -p @0x/contracts-asset-proxy -p @0x/contracts-broker -p @0x/contracts-zero-ex -m --serial -c test:circleci
 | 
			
		||||
    test-publish:
 | 
			
		||||
        resource_class: medium+
 | 
			
		||||
        resource_class: large
 | 
			
		||||
        environment:
 | 
			
		||||
            NODE_OPTIONS: '--max-old-space-size=6442'
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
            - image: 0xorg/verdaccio
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
@@ -95,7 +97,7 @@ jobs:
 | 
			
		||||
                  path: ~/.npm/_logs
 | 
			
		||||
    test-doc-generation:
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
@@ -106,18 +108,18 @@ jobs:
 | 
			
		||||
                  no_output_timeout: 1200
 | 
			
		||||
    test-rest:
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
                      - repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contracts-test-utils
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contract-artifacts
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/contract-wrappers-test
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/migrations
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/order-utils
 | 
			
		||||
            - run: yarn wsrun test:circleci @0x/asset-swapper
 | 
			
		||||
            - run: yarn wsrun -p @0x/contracts-test-utils -m --serial -c test:circleci
 | 
			
		||||
            - run: yarn wsrun -p @0x/contract-artifacts -m --serial -c test:circleci
 | 
			
		||||
            - run: yarn wsrun -p @0x/contract-wrappers-test -m --serial -c test:circleci
 | 
			
		||||
            - run: yarn wsrun -p @0x/migrations -m --serial -c test:circleci
 | 
			
		||||
            - run: yarn wsrun -p @0x/order-utils -m --serial -c test:circleci
 | 
			
		||||
            - run: yarn wsrun -p @0x/asset-swapper -m --serial -c test:circleci
 | 
			
		||||
            - save_cache:
 | 
			
		||||
                  key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
                  paths:
 | 
			
		||||
@@ -134,7 +136,7 @@ jobs:
 | 
			
		||||
        resource_class: large
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
@@ -145,7 +147,7 @@ jobs:
 | 
			
		||||
            - run: yarn diff_md_docs:ci
 | 
			
		||||
    submit-coverage:
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: nikolaik/python-nodejs:python3.7-nodejs10
 | 
			
		||||
            - image: node:12
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "3.7.11",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "3.7.10",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.7.11 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.7.10 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-asset-proxy",
 | 
			
		||||
    "version": "3.7.10",
 | 
			
		||||
    "version": "3.7.11",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -51,13 +51,13 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contract-wrappers": "^13.16.1",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
@@ -79,16 +79,16 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@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/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-erc1155": "^2.1.29",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-erc721": "^3.1.29",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "lodash": "^4.17.11"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "1.1.29",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "1.1.28",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.1.29 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.1.28 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-broker",
 | 
			
		||||
    "version": "1.1.28",
 | 
			
		||||
    "version": "1.1.29",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -51,20 +51,20 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-erc721": "^3.1.29",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.30",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -84,10 +84,10 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/order-utils": "^10.4.20",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "3.1.30",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "3.1.29",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.1.30 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.1.29 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-coordinator",
 | 
			
		||||
    "version": "3.1.29",
 | 
			
		||||
    "version": "3.1.30",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,17 +52,17 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-dev-utils": "^1.3.28",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -82,16 +82,16 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^3.0.26",
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.0.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/assert": "^3.0.27",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.1.0",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.30",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/json-schemas": "^6.1.3",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "http-status-codes": "^1.3.2"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "1.3.28",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "1.3.27",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.3.28 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.3.27 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-dev-utils",
 | 
			
		||||
    "version": "1.3.27",
 | 
			
		||||
    "version": "1.3.28",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -41,17 +41,17 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/assert": "^3.0.27",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
        "npm-run-all": "^4.1.2",
 | 
			
		||||
@@ -63,7 +63,7 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@types/node": "12.12.54"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "2.1.29",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "2.1.28",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v2.1.29 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v2.1.28 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-erc1155",
 | 
			
		||||
    "version": "2.1.28",
 | 
			
		||||
    "version": "2.1.29",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,11 +52,11 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
@@ -80,10 +80,10 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.3.25",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "lodash": "^4.17.11"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "3.3.8",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "3.3.7",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.3.8 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.3.7 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-erc20",
 | 
			
		||||
    "version": "3.3.7",
 | 
			
		||||
    "version": "3.3.8",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -51,18 +51,18 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@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",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -82,7 +82,7 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2"
 | 
			
		||||
        "@0x/base-contract": "^6.4.0"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "3.1.29",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "3.1.28",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.1.29 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.1.28 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-erc721",
 | 
			
		||||
    "version": "3.1.28",
 | 
			
		||||
    "version": "3.1.29",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,18 +52,18 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@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",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -84,7 +84,7 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2"
 | 
			
		||||
        "@0x/base-contract": "^6.4.0"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "4.2.30",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "4.2.29",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v4.2.30 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.2.29 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-exchange-forwarder",
 | 
			
		||||
    "version": "4.2.29",
 | 
			
		||||
    "version": "4.2.30",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,25 +52,25 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-dev-utils": "^1.3.28",
 | 
			
		||||
        "@0x/contracts-erc1155": "^2.1.29",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-erc721": "^3.1.29",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.30",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -90,7 +90,7 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "ethereum-types": "^3.5.0"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "4.3.29",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "4.3.28",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v4.3.29 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.3.28 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-exchange-libs",
 | 
			
		||||
    "version": "4.3.28",
 | 
			
		||||
    "version": "4.3.29",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,14 +52,14 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/subproviders": "^6.5.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -80,13 +80,13 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@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/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "3.2.30",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "3.2.29",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.2.30 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.2.29 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-exchange",
 | 
			
		||||
    "version": "3.2.29",
 | 
			
		||||
    "version": "3.2.30",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,21 +52,21 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-multisig": "^4.1.30",
 | 
			
		||||
        "@0x/contracts-staking": "^2.0.37",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -88,13 +88,13 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@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",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-dev-utils": "^1.3.28",
 | 
			
		||||
        "@0x/contracts-erc1155": "^2.1.29",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-erc721": "^3.1.29",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "lodash": "^4.17.11"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "6.2.24",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "6.2.23",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v6.2.24 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v6.2.23 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-extensions",
 | 
			
		||||
    "version": "6.2.23",
 | 
			
		||||
    "version": "6.2.24",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -52,23 +52,23 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-dev-utils": "^1.3.28",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-erc721": "^3.1.29",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.30",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -90,8 +90,8 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.3.25",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "ethereum-types": "^3.5.0"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-integrations",
 | 
			
		||||
    "version": "2.7.37",
 | 
			
		||||
    "version": "2.7.41",
 | 
			
		||||
    "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.5.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.0.0",
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.1.0",
 | 
			
		||||
        "@0x/contract-wrappers": "^13.16.1",
 | 
			
		||||
        "@0x/contracts-broker": "^1.1.29",
 | 
			
		||||
        "@0x/contracts-coordinator": "^3.1.30",
 | 
			
		||||
        "@0x/contracts-dev-utils": "^1.3.28",
 | 
			
		||||
        "@0x/contracts-exchange-forwarder": "^4.2.30",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-extensions": "^6.2.24",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/coordinator-server": "^1.0.5",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.6",
 | 
			
		||||
        "@0x/migrations": "^8.0.3",
 | 
			
		||||
        "@0x/order-utils": "^10.4.20",
 | 
			
		||||
        "@0x/protocol-utils": "^1.5.1",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.2",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/migrations": "^8.0.6",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/protocol-utils": "^1.6.0",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@azure/core-asynciterator-polyfill": "^1.0.0",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
@@ -93,21 +93,21 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/asset-swapper": "^6.8.0",
 | 
			
		||||
        "@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.1",
 | 
			
		||||
        "@0x/subproviders": "^6.5.2",
 | 
			
		||||
        "@0x/asset-swapper": "^6.11.0",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-erc1155": "^2.1.29",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-erc721": "^3.1.29",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.30",
 | 
			
		||||
        "@0x/contracts-multisig": "^4.1.30",
 | 
			
		||||
        "@0x/contracts-staking": "^2.0.37",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-zero-ex": "^0.23.0",
 | 
			
		||||
        "@0x/subproviders": "^6.5.3",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10",
 | 
			
		||||
        "lodash": "^4.17.11"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "4.1.30",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "4.1.29",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v4.1.30 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.1.29 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-multisig",
 | 
			
		||||
    "version": "4.1.29",
 | 
			
		||||
    "version": "4.1.30",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -49,18 +49,18 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -78,7 +78,7 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "ethereum-types": "^3.5.0"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "2.0.37",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Patch epoch finalization issue",
 | 
			
		||||
                "pr": 221
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1620214333
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "2.0.36",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v2.0.37 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Patch epoch finalization issue (#221)
 | 
			
		||||
 | 
			
		||||
## v2.0.36 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								contracts/staking/contracts/src/StakingPatch.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								contracts/staking/contracts/src/StakingPatch.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2019 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.5.9;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IStaking.sol";
 | 
			
		||||
import "./sys/MixinParams.sol";
 | 
			
		||||
import "./stake/MixinStake.sol";
 | 
			
		||||
import "./fees/MixinExchangeFees.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract StakingPatch is
 | 
			
		||||
    IStaking,
 | 
			
		||||
    MixinParams,
 | 
			
		||||
    MixinStake,
 | 
			
		||||
    MixinExchangeFees
 | 
			
		||||
{
 | 
			
		||||
    /// @dev Initialize storage owned by this contract.
 | 
			
		||||
    ///      This function should not be called directly.
 | 
			
		||||
    ///      The StakingProxy contract will call it in `attachStakingContract()`.
 | 
			
		||||
    function init()
 | 
			
		||||
        public
 | 
			
		||||
        onlyAuthorized
 | 
			
		||||
    {
 | 
			
		||||
        uint256 currentEpoch_ = currentEpoch;
 | 
			
		||||
        uint256 prevEpoch = currentEpoch_.safeSub(1);
 | 
			
		||||
 | 
			
		||||
        // Patch corrupted state
 | 
			
		||||
        aggregatedStatsByEpoch[prevEpoch].numPoolsToFinalize = 0;
 | 
			
		||||
        this.endEpoch();
 | 
			
		||||
 | 
			
		||||
        uint256 lastPoolId_ = 57;
 | 
			
		||||
        for (uint256 i = 1; i <= lastPoolId_; i++) {
 | 
			
		||||
            this.finalizePool(bytes32(i));
 | 
			
		||||
        }
 | 
			
		||||
        // Ensure that current epoch's state is not corrupted
 | 
			
		||||
        aggregatedStatsByEpoch[currentEpoch_].numPoolsToFinalize = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -53,6 +53,10 @@ contract MixinExchangeFees is
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidProtocolFee(protocolFee);
 | 
			
		||||
 | 
			
		||||
        if (protocolFee == 0) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Transfer the protocol fee to this address if it should be paid in
 | 
			
		||||
        // WETH.
 | 
			
		||||
        if (msg.value == 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-staking",
 | 
			
		||||
    "version": "2.0.36",
 | 
			
		||||
    "version": "2.0.37",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
    "config": {
 | 
			
		||||
        "publicInterfaceContracts": "IStaking,IStakingEvents,IStakingProxy,IZrxVault,LibStakingRichErrors,Staking,StakingProxy,ZrxVault,TestStaking",
 | 
			
		||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolRewards|MixinStorage|Staking|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestExchangeManager|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibSafeDowncast|TestMixinCumulativeRewards|TestMixinParams|TestMixinScheduler|TestMixinStake|TestMixinStakeBalances|TestMixinStakeStorage|TestMixinStakingPool|TestMixinStakingPoolRewards|TestProtocolFees|TestProxyDestination|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStakingProxyUnit|TestStorageLayoutAndConstants|ZrxVault).json"
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolRewards|MixinStorage|Staking|StakingPatch|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestExchangeManager|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibSafeDowncast|TestMixinCumulativeRewards|TestMixinParams|TestMixinScheduler|TestMixinStake|TestMixinStakeBalances|TestMixinStakeStorage|TestMixinStakingPool|TestMixinStakingPoolRewards|TestProtocolFees|TestProxyDestination|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStakingProxyUnit|TestStorageLayoutAndConstants|ZrxVault).json"
 | 
			
		||||
    },
 | 
			
		||||
    "repository": {
 | 
			
		||||
        "type": "git",
 | 
			
		||||
@@ -53,20 +53,20 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-dev-utils": "^1.3.28",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
        "chai": "^4.0.1",
 | 
			
		||||
@@ -87,10 +87,10 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.3.25",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ import * as MixinStakingPool from '../test/generated-artifacts/MixinStakingPool.
 | 
			
		||||
import * as MixinStakingPoolRewards from '../test/generated-artifacts/MixinStakingPoolRewards.json';
 | 
			
		||||
import * as MixinStorage from '../test/generated-artifacts/MixinStorage.json';
 | 
			
		||||
import * as Staking from '../test/generated-artifacts/Staking.json';
 | 
			
		||||
import * as StakingPatch from '../test/generated-artifacts/StakingPatch.json';
 | 
			
		||||
import * as StakingProxy from '../test/generated-artifacts/StakingProxy.json';
 | 
			
		||||
import * as TestAssertStorageParams from '../test/generated-artifacts/TestAssertStorageParams.json';
 | 
			
		||||
import * as TestCobbDouglas from '../test/generated-artifacts/TestCobbDouglas.json';
 | 
			
		||||
@@ -61,6 +62,7 @@ import * as TestStorageLayoutAndConstants from '../test/generated-artifacts/Test
 | 
			
		||||
import * as ZrxVault from '../test/generated-artifacts/ZrxVault.json';
 | 
			
		||||
export const artifacts = {
 | 
			
		||||
    Staking: Staking as ContractArtifact,
 | 
			
		||||
    StakingPatch: StakingPatch as ContractArtifact,
 | 
			
		||||
    StakingProxy: StakingProxy as ContractArtifact,
 | 
			
		||||
    ZrxVault: ZrxVault as ContractArtifact,
 | 
			
		||||
    MixinExchangeFees: MixinExchangeFees as ContractArtifact,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								contracts/staking/test/patch_mainnet_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								contracts/staking/test/patch_mainnet_test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
import { blockchainTests, constants, expect, filterLogsToArguments } from '@0x/contracts-test-utils';
 | 
			
		||||
import { BigNumber, logUtils } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { artifacts } from './artifacts';
 | 
			
		||||
import { StakingEvents, StakingPatchContract, StakingProxyContract, StakingProxyEvents } from './wrappers';
 | 
			
		||||
 | 
			
		||||
const abis = _.mapValues(artifacts, v => v.compilerOutput.abi);
 | 
			
		||||
const STAKING_PROXY = '0xa26e80e7dea86279c6d778d702cc413e6cffa777';
 | 
			
		||||
const STAKING_OWNER = '0x7d3455421bbc5ed534a83c88fd80387dc8271392';
 | 
			
		||||
const EXCHANGE_PROXY = '0xdef1c0ded9bec7f1a1670819833240f027b25eff';
 | 
			
		||||
blockchainTests.configure({
 | 
			
		||||
    fork: {
 | 
			
		||||
        unlockedAccounts: [STAKING_OWNER, EXCHANGE_PROXY],
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
blockchainTests.fork('Staking patch mainnet fork tests', env => {
 | 
			
		||||
    let stakingProxyContract: StakingProxyContract;
 | 
			
		||||
    let patchedStakingPatchContract: StakingPatchContract;
 | 
			
		||||
 | 
			
		||||
    before(async () => {
 | 
			
		||||
        stakingProxyContract = new StakingProxyContract(STAKING_PROXY, env.provider, undefined, abis);
 | 
			
		||||
        patchedStakingPatchContract = await StakingPatchContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.Staking,
 | 
			
		||||
            env.provider,
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            artifacts,
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('Staking proxy successfully attaches to patched logic', async () => {
 | 
			
		||||
        const tx = await stakingProxyContract
 | 
			
		||||
            .attachStakingContract(patchedStakingPatchContract.address)
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: STAKING_OWNER, gasPrice: 0 }, { shouldValidate: false });
 | 
			
		||||
        expect(filterLogsToArguments(tx.logs, StakingProxyEvents.StakingContractAttachedToProxy)).to.deep.equal([
 | 
			
		||||
            {
 | 
			
		||||
                newStakingPatchContractAddress: patchedStakingPatchContract.address,
 | 
			
		||||
            },
 | 
			
		||||
        ]);
 | 
			
		||||
        expect(filterLogsToArguments(tx.logs, StakingEvents.EpochEnded).length).to.equal(1);
 | 
			
		||||
        expect(filterLogsToArguments(tx.logs, StakingEvents.EpochFinalized).length).to.equal(1);
 | 
			
		||||
        logUtils.log(`${tx.gasUsed} gas used`);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('Patched staking handles 0 gas protocol fees', async () => {
 | 
			
		||||
        const staking = new StakingPatchContract(STAKING_PROXY, env.provider, undefined, abis);
 | 
			
		||||
        const maker = '0x7b1886e49ab5433bb46f7258548092dc8cdca28b';
 | 
			
		||||
        const zeroFeeTx = await staking
 | 
			
		||||
            .payProtocolFee(maker, constants.NULL_ADDRESS, constants.ZERO_AMOUNT)
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: EXCHANGE_PROXY, gasPrice: 0 }, { shouldValidate: false });
 | 
			
		||||
        // StakingPoolEarnedRewardsInEpoch should _not_ be emitted for a zero protocol fee.
 | 
			
		||||
        // tslint:disable-next-line:no-unused-expression
 | 
			
		||||
        expect(filterLogsToArguments(zeroFeeTx.logs, StakingEvents.StakingPoolEarnedRewardsInEpoch)).to.be.empty;
 | 
			
		||||
 | 
			
		||||
        // Coincidentally there's some ETH in the ExchangeProxy
 | 
			
		||||
        const nonZeroFeeTx = await staking
 | 
			
		||||
            .payProtocolFee(maker, constants.NULL_ADDRESS, new BigNumber(1))
 | 
			
		||||
            .awaitTransactionSuccessAsync({ from: EXCHANGE_PROXY, gasPrice: 0, value: 1 }, { shouldValidate: false });
 | 
			
		||||
        // StakingPoolEarnedRewardsInEpoch _should_ be emitted for a non-zero protocol fee.
 | 
			
		||||
        expect(
 | 
			
		||||
            filterLogsToArguments(nonZeroFeeTx.logs, StakingEvents.StakingPoolEarnedRewardsInEpoch),
 | 
			
		||||
        ).to.have.lengthOf(1);
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
// tslint:enable:no-unnecessary-type-assertion
 | 
			
		||||
@@ -31,6 +31,7 @@ export * from '../test/generated-wrappers/mixin_staking_pool';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_staking_pool_rewards';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_storage';
 | 
			
		||||
export * from '../test/generated-wrappers/staking';
 | 
			
		||||
export * from '../test/generated-wrappers/staking_patch';
 | 
			
		||||
export * from '../test/generated-wrappers/staking_proxy';
 | 
			
		||||
export * from '../test/generated-wrappers/test_assert_storage_params';
 | 
			
		||||
export * from '../test/generated-wrappers/test_cobb_douglas';
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,7 @@
 | 
			
		||||
        "test/generated-artifacts/MixinStakingPoolRewards.json",
 | 
			
		||||
        "test/generated-artifacts/MixinStorage.json",
 | 
			
		||||
        "test/generated-artifacts/Staking.json",
 | 
			
		||||
        "test/generated-artifacts/StakingPatch.json",
 | 
			
		||||
        "test/generated-artifacts/StakingProxy.json",
 | 
			
		||||
        "test/generated-artifacts/TestAssertStorageParams.json",
 | 
			
		||||
        "test/generated-artifacts/TestCobbDouglas.json",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "5.4.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Set default ganache gas limit to 100e6",
 | 
			
		||||
                "pr": 197
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1620214333
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "5.3.25",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v5.4.0 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Set default ganache gas limit to 100e6 (#197)
 | 
			
		||||
 | 
			
		||||
## v5.3.25 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-test-utils",
 | 
			
		||||
    "version": "5.3.25",
 | 
			
		||||
    "version": "5.4.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.2",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "npm-run-all": "^4.1.2",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
@@ -42,20 +42,20 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^3.0.26",
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.0.0",
 | 
			
		||||
        "@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/assert": "^3.0.27",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.1.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/json-schemas": "^6.1.3",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-coverage": "^4.0.37",
 | 
			
		||||
        "@0x/sol-profiler": "^4.1.27",
 | 
			
		||||
        "@0x/sol-trace": "^3.0.37",
 | 
			
		||||
        "@0x/subproviders": "^6.5.3",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/bn.js": "^4.11.0",
 | 
			
		||||
        "@types/js-combinatorics": "^0.5.29",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ export let providerConfigs: Web3Config = {
 | 
			
		||||
    shouldUseInProcessGanache: true,
 | 
			
		||||
    shouldAllowUnlimitedContractSize: true,
 | 
			
		||||
    hardfork: 'istanbul',
 | 
			
		||||
    gasLimit: 100e6,
 | 
			
		||||
    unlocked_accounts: [
 | 
			
		||||
        '0x6cc5f688a315f3dc28a7781717a9a798a59fda7b',
 | 
			
		||||
        '0x55dc8f21d20d4c6ed3c82916a438a413ca68e335',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,23 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1620214333,
 | 
			
		||||
        "version": "1.1.6",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "1.1.5",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Patched votingPower logic",
 | 
			
		||||
                "pr": 214
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1619825976
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "1.1.4",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.1.6 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.1.5 - _April 30, 2021_
 | 
			
		||||
 | 
			
		||||
    * Patched votingPower logic (#214)
 | 
			
		||||
 | 
			
		||||
## v1.1.4 - _April 28, 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.4",
 | 
			
		||||
    "version": "1.1.6",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -46,14 +46,14 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.5.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.0.0",
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.1.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-staking": "^2.0.37",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@types/isomorphic-fetch": "^0.0.35",
 | 
			
		||||
@@ -72,13 +72,13 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/protocol-utils": "^1.5.1",
 | 
			
		||||
        "@0x/subproviders": "^6.5.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/protocol-utils": "^1.6.0",
 | 
			
		||||
        "@0x/subproviders": "^6.5.3",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -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": 1620214333,
 | 
			
		||||
        "version": "4.7.8",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1619596077,
 | 
			
		||||
        "version": "4.7.7",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v4.7.8 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.7.7 - _April 28, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-utils",
 | 
			
		||||
    "version": "4.7.7",
 | 
			
		||||
    "version": "4.7.8",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -50,15 +50,15 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@types/bn.js": "^4.11.0",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
@@ -79,9 +79,9 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "bn.js": "^4.11.8",
 | 
			
		||||
        "ethereum-types": "^3.5.0"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,36 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "0.23.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Added ETH support to `MixinCurve`",
 | 
			
		||||
                "pr": 220
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add Balancer V2 integration",
 | 
			
		||||
                "pr": 206
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1620214333
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "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": [
 | 
			
		||||
@@ -25,6 +57,10 @@
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap)",
 | 
			
		||||
                "pr": 208
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v0.23.0 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Added ETH support to `MixinCurve` (#220)
 | 
			
		||||
    * Add Balancer V2 integration (#206)
 | 
			
		||||
 | 
			
		||||
## 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)
 | 
			
		||||
@@ -16,6 +29,7 @@ CHANGELOG
 | 
			
		||||
## v0.21.1 - _April 12, 2021_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
    * BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap) (#208)
 | 
			
		||||
 | 
			
		||||
## v0.21.0 - _April 1, 2021_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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))
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
import "./IBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinBalancer.sol";
 | 
			
		||||
import "./mixins/MixinBalancerV2.sol";
 | 
			
		||||
import "./mixins/MixinBancor.sol";
 | 
			
		||||
import "./mixins/MixinCoFiX.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
@@ -38,11 +39,13 @@ import "./mixins/MixinOasis.sol";
 | 
			
		||||
import "./mixins/MixinShell.sol";
 | 
			
		||||
import "./mixins/MixinUniswap.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV2.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV3.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract BridgeAdapter is
 | 
			
		||||
    IBridgeAdapter,
 | 
			
		||||
    MixinBalancer,
 | 
			
		||||
    MixinBalancerV2,
 | 
			
		||||
    MixinBancor,
 | 
			
		||||
    MixinCoFiX,
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
@@ -58,14 +61,16 @@ contract BridgeAdapter is
 | 
			
		||||
    MixinShell,
 | 
			
		||||
    MixinUniswap,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
    MixinUniswapV3,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinBalancer()
 | 
			
		||||
        MixinBalancerV2()
 | 
			
		||||
        MixinBancor(weth)
 | 
			
		||||
        MixinCoFiX()
 | 
			
		||||
        MixinCurve()
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
        MixinCryptoCom()
 | 
			
		||||
        MixinDodo()
 | 
			
		||||
        MixinDodoV2()
 | 
			
		||||
@@ -78,6 +83,7 @@ contract BridgeAdapter is
 | 
			
		||||
        MixinShell()
 | 
			
		||||
        MixinUniswap(weth)
 | 
			
		||||
        MixinUniswapV2()
 | 
			
		||||
        MixinUniswapV3()
 | 
			
		||||
        MixinZeroExBridge()
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
@@ -99,6 +105,12 @@ contract BridgeAdapter is
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV3) {
 | 
			
		||||
            boughtAmount = _tradeUniswapV3(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -119,6 +131,13 @@ contract BridgeAdapter is
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCERV2) {
 | 
			
		||||
            boughtAmount = _tradeBalancerV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.KYBER) {
 | 
			
		||||
            boughtAmount = _tradeKyber(
 | 
			
		||||
                sellToken,
 | 
			
		||||
 
 | 
			
		||||
@@ -44,4 +44,6 @@ library BridgeProtocols {
 | 
			
		||||
    uint128 internal constant COFIX       = 14;
 | 
			
		||||
    uint128 internal constant NERVE       = 15;
 | 
			
		||||
    uint128 internal constant MAKERPSM    = 16;
 | 
			
		||||
    uint128 internal constant BALANCERV2  = 17;
 | 
			
		||||
    uint128 internal constant UNISWAPV3   = 18;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,117 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IBalancerV2Vault {
 | 
			
		||||
 | 
			
		||||
    enum SwapKind { GIVEN_IN, GIVEN_OUT }
 | 
			
		||||
    /**
 | 
			
		||||
     * @dev Performs a swap with a single Pool.
 | 
			
		||||
     *
 | 
			
		||||
     * If the swap is given in (the number of tokens to send to the Pool is known), returns the amount of tokens
 | 
			
		||||
     * taken from the Pool, which must be greater than or equal to `limit`.
 | 
			
		||||
     *
 | 
			
		||||
     * If the swap is given out (the number of tokens to take from the Pool is known), returns the amount of
 | 
			
		||||
     * tokens sent to the Pool, which must be less than or equal to `limit`.
 | 
			
		||||
     *
 | 
			
		||||
     * Internal Balance usage and the recipient are determined by the `funds` struct.
 | 
			
		||||
     *
 | 
			
		||||
     * Emits a `Swap` event.
 | 
			
		||||
     * For full documentation see https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/vault/interfaces/IVault.sol
 | 
			
		||||
     */
 | 
			
		||||
    function swap(
 | 
			
		||||
        SingleSwap calldata request,
 | 
			
		||||
        FundManagement calldata funds,
 | 
			
		||||
        uint256 limit,
 | 
			
		||||
        uint256 deadline
 | 
			
		||||
    ) external payable returns (uint256);
 | 
			
		||||
 | 
			
		||||
    struct SingleSwap {
 | 
			
		||||
        bytes32 poolId;
 | 
			
		||||
        SwapKind kind;
 | 
			
		||||
        IERC20TokenV06 assetIn;
 | 
			
		||||
        IERC20TokenV06 assetOut;
 | 
			
		||||
        uint256 amount;
 | 
			
		||||
        bytes userData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct FundManagement {
 | 
			
		||||
        address sender;
 | 
			
		||||
        bool fromInternalBalance;
 | 
			
		||||
        address payable recipient;
 | 
			
		||||
        bool toInternalBalance;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinBalancerV2 {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    struct BalancerV2BridgeData {
 | 
			
		||||
        IBalancerV2Vault vault;
 | 
			
		||||
        bytes32 poolId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _tradeBalancerV2(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        // Decode the bridge data.
 | 
			
		||||
        BalancerV2BridgeData memory data = abi.decode(bridgeData, (BalancerV2BridgeData));
 | 
			
		||||
 | 
			
		||||
        // Grant an allowance to the exchange to spend `fromTokenAddress` token.
 | 
			
		||||
        sellToken.approveIfBelow(address(data.vault), sellAmount);
 | 
			
		||||
 | 
			
		||||
        // Sell the entire sellAmount
 | 
			
		||||
        IBalancerV2Vault.SingleSwap memory request = IBalancerV2Vault.SingleSwap({
 | 
			
		||||
            poolId: data.poolId,
 | 
			
		||||
            kind: IBalancerV2Vault.SwapKind.GIVEN_IN,
 | 
			
		||||
            assetIn: sellToken,
 | 
			
		||||
            assetOut: buyToken,
 | 
			
		||||
            amount: sellAmount, // amount in
 | 
			
		||||
            userData: ""
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        IBalancerV2Vault.FundManagement memory funds = IBalancerV2Vault.FundManagement({
 | 
			
		||||
            sender: address(this),
 | 
			
		||||
            fromInternalBalance: false,
 | 
			
		||||
            recipient: payable(address(this)),
 | 
			
		||||
            toInternalBalance: false
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        boughtAmount = data.vault.swap(
 | 
			
		||||
            request,
 | 
			
		||||
            funds,
 | 
			
		||||
            1, // min amount out
 | 
			
		||||
            block.timestamp // expires after this block
 | 
			
		||||
        );
 | 
			
		||||
        return boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -21,6 +21,7 @@ pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
@@ -31,6 +32,15 @@ contract MixinCurve {
 | 
			
		||||
    using LibSafeMathV06 for uint256;
 | 
			
		||||
    using LibRichErrorsV06 for bytes;
 | 
			
		||||
 | 
			
		||||
    /// @dev Mainnet address of the WETH contract.
 | 
			
		||||
    IEtherTokenV06 private immutable WETH;
 | 
			
		||||
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
    {
 | 
			
		||||
        WETH = weth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    struct CurveBridgeData {
 | 
			
		||||
        address curveAddress;
 | 
			
		||||
@@ -50,10 +60,17 @@ contract MixinCurve {
 | 
			
		||||
    {
 | 
			
		||||
        // Decode the bridge data to get the Curve metadata.
 | 
			
		||||
        CurveBridgeData memory data = abi.decode(bridgeData, (CurveBridgeData));
 | 
			
		||||
        sellToken.approveIfBelow(data.curveAddress, sellAmount);
 | 
			
		||||
        uint256 payableAmount;
 | 
			
		||||
        if (sellToken == WETH) {
 | 
			
		||||
            payableAmount = sellAmount;
 | 
			
		||||
            WETH.withdraw(sellAmount);
 | 
			
		||||
        } else {
 | 
			
		||||
            sellToken.approveIfBelow(data.curveAddress, sellAmount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uint256 beforeBalance = buyToken.balanceOf(address(this));
 | 
			
		||||
        (bool success, bytes memory resultData) =
 | 
			
		||||
            data.curveAddress.call(abi.encodeWithSelector(
 | 
			
		||||
            data.curveAddress.call{value: payableAmount}(abi.encodeWithSelector(
 | 
			
		||||
                data.exchangeFunctionSelector,
 | 
			
		||||
                data.fromCoinIdx,
 | 
			
		||||
                data.toCoinIdx,
 | 
			
		||||
@@ -65,6 +82,12 @@ contract MixinCurve {
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            resultData.rrevert();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (buyToken == WETH) {
 | 
			
		||||
            boughtAmount = address(this).balance;
 | 
			
		||||
            WETH.deposit{ value: boughtAmount }();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return buyToken.balanceOf(address(this)).safeSub(beforeBalance);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,70 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../IBridgeAdapter.sol";
 | 
			
		||||
 | 
			
		||||
interface IUniswapV3Router {
 | 
			
		||||
 | 
			
		||||
    struct ExactInputParams {
 | 
			
		||||
        bytes path;
 | 
			
		||||
        address recipient;
 | 
			
		||||
        uint256 deadline;
 | 
			
		||||
        uint256 amountIn;
 | 
			
		||||
        uint256 amountOutMinimum;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function exactInput(ExactInputParams memory params)
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint256 amountOut);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinUniswapV3 {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    function _tradeUniswapV3(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (IUniswapV3Router router, bytes memory path) =
 | 
			
		||||
            abi.decode(bridgeData, (IUniswapV3Router, bytes));
 | 
			
		||||
 | 
			
		||||
        // Grant the Uniswap router an allowance to sell the sell token.
 | 
			
		||||
        sellToken.approveIfBelow(address(router), sellAmount);
 | 
			
		||||
 | 
			
		||||
        boughtAmount = router.exactInput(IUniswapV3Router.ExactInputParams({
 | 
			
		||||
            path: path,
 | 
			
		||||
            recipient: address(this),
 | 
			
		||||
            deadline: block.timestamp,
 | 
			
		||||
            amountIn: sellAmount,
 | 
			
		||||
            amountOutMinimum: 1
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-zero-ex",
 | 
			
		||||
    "version": "0.22.1",
 | 
			
		||||
    "version": "0.23.0",
 | 
			
		||||
    "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|TestOrderSignerRegistryWithContractWallet|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|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinDodoV2|MixinKyber|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|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,14 +55,14 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.5.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.0.0",
 | 
			
		||||
        "@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/abi-gen": "^5.6.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.1.0",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/order-utils": "^10.4.21",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@types/isomorphic-fetch": "^0.0.35",
 | 
			
		||||
@@ -82,13 +82,13 @@
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.3.2",
 | 
			
		||||
        "@0x/protocol-utils": "^1.5.1",
 | 
			
		||||
        "@0x/subproviders": "^6.5.2",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/protocol-utils": "^1.6.0",
 | 
			
		||||
        "@0x/subproviders": "^6.5.3",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,7 @@ import * as LiquidityProviderSandbox from '../test/generated-artifacts/Liquidity
 | 
			
		||||
import * as LogMetadataTransformer from '../test/generated-artifacts/LogMetadataTransformer.json';
 | 
			
		||||
import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransactionsFeature.json';
 | 
			
		||||
import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
 | 
			
		||||
import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json';
 | 
			
		||||
import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
 | 
			
		||||
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
 | 
			
		||||
import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json';
 | 
			
		||||
@@ -91,6 +92,7 @@ import * as MixinOasis from '../test/generated-artifacts/MixinOasis.json';
 | 
			
		||||
import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
 | 
			
		||||
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
 | 
			
		||||
import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json';
 | 
			
		||||
import * as MixinUniswapV3 from '../test/generated-artifacts/MixinUniswapV3.json';
 | 
			
		||||
import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridge.json';
 | 
			
		||||
import * as MooniswapLiquidityProvider from '../test/generated-artifacts/MooniswapLiquidityProvider.json';
 | 
			
		||||
import * as MultiplexFeature from '../test/generated-artifacts/MultiplexFeature.json';
 | 
			
		||||
@@ -235,6 +237,7 @@ export const artifacts = {
 | 
			
		||||
    BridgeProtocols: BridgeProtocols as ContractArtifact,
 | 
			
		||||
    IBridgeAdapter: IBridgeAdapter as ContractArtifact,
 | 
			
		||||
    MixinBalancer: MixinBalancer as ContractArtifact,
 | 
			
		||||
    MixinBalancerV2: MixinBalancerV2 as ContractArtifact,
 | 
			
		||||
    MixinBancor: MixinBancor as ContractArtifact,
 | 
			
		||||
    MixinCoFiX: MixinCoFiX as ContractArtifact,
 | 
			
		||||
    MixinCryptoCom: MixinCryptoCom as ContractArtifact,
 | 
			
		||||
@@ -250,6 +253,7 @@ export const artifacts = {
 | 
			
		||||
    MixinShell: MixinShell as ContractArtifact,
 | 
			
		||||
    MixinUniswap: MixinUniswap as ContractArtifact,
 | 
			
		||||
    MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
 | 
			
		||||
    MixinUniswapV3: MixinUniswapV3 as ContractArtifact,
 | 
			
		||||
    MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
 | 
			
		||||
    ILiquidityProvider: ILiquidityProvider as ContractArtifact,
 | 
			
		||||
    IMooniswapPool: IMooniswapPool as ContractArtifact,
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,7 @@ export * from '../test/generated-wrappers/liquidity_provider_sandbox';
 | 
			
		||||
export * from '../test/generated-wrappers/log_metadata_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/meta_transactions_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_balancer';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_balancer_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_bancor';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_co_fi_x';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_crypto_com';
 | 
			
		||||
@@ -89,6 +90,7 @@ export * from '../test/generated-wrappers/mixin_oasis';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_shell';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_uniswap';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_uniswap_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_uniswap_v3';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_zero_ex_bridge';
 | 
			
		||||
export * from '../test/generated-wrappers/mooniswap_liquidity_provider';
 | 
			
		||||
export * from '../test/generated-wrappers/multiplex_feature';
 | 
			
		||||
 
 | 
			
		||||
@@ -105,6 +105,7 @@
 | 
			
		||||
        "test/generated-artifacts/LogMetadataTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/MetaTransactionsFeature.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBalancer.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBalancerV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBancor.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCoFiX.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCryptoCom.json",
 | 
			
		||||
@@ -120,6 +121,7 @@
 | 
			
		||||
        "test/generated-artifacts/MixinShell.json",
 | 
			
		||||
        "test/generated-artifacts/MixinUniswap.json",
 | 
			
		||||
        "test/generated-artifacts/MixinUniswapV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinUniswapV3.json",
 | 
			
		||||
        "test/generated-artifacts/MixinZeroExBridge.json",
 | 
			
		||||
        "test/generated-artifacts/MooniswapLiquidityProvider.json",
 | 
			
		||||
        "test/generated-artifacts/MultiplexFeature.json",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								package.json
									
									
									
									
									
								
							@@ -10,7 +10,7 @@
 | 
			
		||||
    ],
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "deps_versions:ci": "node ./node_modules/@0x/monorepo-scripts/lib/deps_versions.js",
 | 
			
		||||
        "fix": "wsrun fix $PKG --fast-exit --parallel --exclude-missing",
 | 
			
		||||
        "fix": "wsrun --fast-exit --parallel --exclude-missing -c fix $PKG",
 | 
			
		||||
        "ganache": "ganache-cli -p 8545 --gasLimit 10000000 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
 | 
			
		||||
        "prettier": "prettier --write '**/*.{ts,tsx,json,md}' --config .prettierrc",
 | 
			
		||||
        "prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}' --config .prettierrc",
 | 
			
		||||
@@ -27,31 +27,25 @@
 | 
			
		||||
        "install:all": "yarn install",
 | 
			
		||||
        "wsrun": "wsrun",
 | 
			
		||||
        "lerna": "lerna",
 | 
			
		||||
        "build": "lerna link && wsrun build $PKG -r --stages --fast-exit --exclude-missing",
 | 
			
		||||
        "build:ci": "lerna link && wsrun build:ci $PKG --fast-exit -r --stages --exclude-missing",
 | 
			
		||||
        "build:contracts": "lerna link && wsrun build -p ${npm_package_config_contractsPackages} -c --fast-exit -r --stages --exclude-missing",
 | 
			
		||||
        "build": "lerna link && wsrun -r --stages --fast-exit --exclude-missing -c build $PKG",
 | 
			
		||||
        "build:ci": "lerna link && wsrun --fast-exit -r --stages --exclude-missing -c build:ci $PKG",
 | 
			
		||||
        "build:contracts": "lerna link && wsrun -p ${npm_package_config_contractsPackages} --fast-exit -r --stages --exclude-missing -c build",
 | 
			
		||||
        "build:ts": "tsc -b",
 | 
			
		||||
        "watch:ts": "tsc -b -w",
 | 
			
		||||
        "clean": "wsrun clean $PKG --fast-exit -r --parallel --exclude-missing",
 | 
			
		||||
        "clean:contracts": "wsrun clean -p ${npm_package_config_contractsPackages} -c --fast-exit -r --parallel --exclude-missing",
 | 
			
		||||
        "contracts:gen": "wsrun contracts:gen $PKG --fast-exit -r --parallel --exclude-missing",
 | 
			
		||||
        "contracts:compile": "wsrun compile -p ${npm_package_config_contractsPackages} --fast-exit -r --stages --exclude-missing",
 | 
			
		||||
        "contracts:compile:truffle": "wsrun compile:truffle -p ${npm_package_config_contractsPackages} --fast-exit -r --stages --exclude-missing",
 | 
			
		||||
        "contracts:watch": "wsrun watch $PKG --parallel --exclude-missing",
 | 
			
		||||
        "clean": "wsrun --fast-exit -r --parallel --exclude-missing clean -c $PKG",
 | 
			
		||||
        "contracts:watch": "wsrun --parallel --exclude-missing watch -c $PKG",
 | 
			
		||||
        "remove_node_modules": "lerna clean --yes; rm -rf node_modules",
 | 
			
		||||
        "rebuild": "run-s clean build",
 | 
			
		||||
        "test": "wsrun test $(echo $(echo ${npm_package_config_contractsPackages} ${npm_package_config_nonContractPackages} | tr ' ' '\n' | sort | uniq) ${npm_package_config_ignoreTestsForPackages} | tr ' ' '\n' | sort | uniq -u | tr '\n' ' ') --fast-exit --serial --exclude-missing",
 | 
			
		||||
        "test:all": "wsrun test $PKG --fast-exit --serial --exclude-missing",
 | 
			
		||||
        "test:contracts": "wsrun test --serial -p $(echo ${npm_package_config_contractsPackages} ${npm_package_config_ignoreTestsForPackages} | tr ' ' '\n' | sort | uniq -u | tr '\n' ' ') -c --fast-exit --exclude-missing",
 | 
			
		||||
        "test:contracts:all": "wsrun test --serial -p ${npm_package_config_contractsPackages} -c --fast-exit --exclude-missing",
 | 
			
		||||
        "test": "wsrun --fast-exit --serial --exclude-missing -p $(echo $(echo ${npm_package_config_contractsPackages} ${npm_package_config_nonContractPackages} | tr ' ' '\n' | sort | uniq) ${npm_package_config_ignoreTestsForPackages} | tr ' ' '\n' | sort | uniq -u | tr '\n' ' ') -c test",
 | 
			
		||||
        "test:all": "wsrun --fast-exit --serial --exclude-missing -c test $PKG",
 | 
			
		||||
        "test:contracts": "wsrun --serial -p $(echo ${npm_package_config_contractsPackages} ${npm_package_config_ignoreTestsForPackages} | tr ' ' '\n' | sort | uniq -u | tr '\n' ' ') --fast-exit --exclude-missing -c test",
 | 
			
		||||
        "test:contracts:all": "wsrun --serial -p ${npm_package_config_contractsPackages} --fast-exit --exclude-missing -c test",
 | 
			
		||||
        "generate_doc": "node ./node_modules/@0x/monorepo-scripts/lib/doc_generate.js --config ./doc-gen-config.json",
 | 
			
		||||
        "upload_md_docs": "aws s3 rm --recursive s3://docs-markdown; wsrun s3:sync_md_docs --exclude-missing",
 | 
			
		||||
        "diff_md_docs:ci": "wsrun diff_docs --exclude-missing",
 | 
			
		||||
        "upload_md_docs": "aws s3 rm --recursive s3://docs-markdown; wsrun --exclude-missing -c s3:sync_md_docs",
 | 
			
		||||
        "diff_md_docs:ci": "wsrun --exclude-missing -c diff_docs",
 | 
			
		||||
        "test:generate_docs:circleci": "for i in ${npm_package_config_packagesWithDocPages}; do yarn generate_doc --package $i || break -1; done;",
 | 
			
		||||
        "bundlewatch": "bundlewatch",
 | 
			
		||||
        "lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing",
 | 
			
		||||
        "lint:stages": "wsrun lint $PKG --fast-exit --stages --exclude-missing",
 | 
			
		||||
        "lint:contracts": "wsrun lint -p ${npm_package_config_contractsPackages} -c --fast-exit --stages --exclude-missing",
 | 
			
		||||
        "lint": "wsrun --fast-exit --parallel --exclude-missing -c lint $PKG",
 | 
			
		||||
        "upgrade_org_deps": "node node_modules/@0x/monorepo-scripts/lib/upgrade_deps.js -p '@0x|ethereum-types'",
 | 
			
		||||
        "upgrade_deps": "node node_modules/@0x/monorepo-scripts/lib/upgrade_deps.js",
 | 
			
		||||
        "verdaccio": "docker run --rm -i -p 4873:4873 0xorg/verdaccio"
 | 
			
		||||
@@ -66,7 +60,7 @@
 | 
			
		||||
        "ignoreDependencyVersionsForPackage": "contract-wrappers"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/monorepo-scripts": "^3.1.6",
 | 
			
		||||
        "@0x/monorepo-scripts": "^3.1.7",
 | 
			
		||||
        "@0x-lerna-fork/lerna": "3.16.10",
 | 
			
		||||
        "@0xproject/npm-cli-login": "^0.0.11",
 | 
			
		||||
        "async-child-process": "^1.1.1",
 | 
			
		||||
@@ -78,7 +72,7 @@
 | 
			
		||||
        "prettier": "~1.16.3",
 | 
			
		||||
        "source-map-support": "^0.5.6",
 | 
			
		||||
        "typescript": "4.2.2",
 | 
			
		||||
        "wsrun": "^2.2.0"
 | 
			
		||||
        "wsrun": "^5.2.4"
 | 
			
		||||
    },
 | 
			
		||||
    "resolutions": {
 | 
			
		||||
        "merkle-patricia-tree": "^2.3.2"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,91 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "6.11.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add price comparisons data separate from the quote report",
 | 
			
		||||
                "pr": 219
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add caching for top Balancer V2 pools on startup and during regular intervals",
 | 
			
		||||
                "pr": 228
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Tweak compiler settings for smaller sampler bytecode",
 | 
			
		||||
                "pr": 229
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix Multiplex multihop encoding for ETH buys/sells",
 | 
			
		||||
                "pr": 230
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix Sampler address override for Ganache",
 | 
			
		||||
                "pr": 232
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1620362129
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "6.10.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Reactivate PancakeSwapV2 and BakerySwap VIP on BSC",
 | 
			
		||||
                "pr": 222
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add LUSD Curve pool",
 | 
			
		||||
                "pr": 218
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix exchangeProxyGasOverhead for fallback path",
 | 
			
		||||
                "pr": 215
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Enable ETH based Curve pools",
 | 
			
		||||
                "pr": 220
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Reactivate PancakeSwapV2 and BakerySwap VIP on BSC",
 | 
			
		||||
                "pr": 222
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Disable WETH based SnowSwap pools",
 | 
			
		||||
                "pr": 220
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "PLP now includes a fallback due to observed collisions",
 | 
			
		||||
                "pr": 223
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add Balancer V2 integration",
 | 
			
		||||
                "pr": 206
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Re-work the PoolCache for Balancer et al",
 | 
			
		||||
                "pr": 226
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1620214333
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "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": [
 | 
			
		||||
@@ -38,6 +125,10 @@
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Support `Ropsten` network",
 | 
			
		||||
                "pr": 203
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "BSC Uniswap clones (ApeSwap, CafeSwap, CheeseSwap, JulSwap), Saddle BTC pool, Curve gas schedule",
 | 
			
		||||
                "pr": 208
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1618592834
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,34 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v6.11.0 - _May 7, 2021_
 | 
			
		||||
 | 
			
		||||
    * Add price comparisons data separate from the quote report (#219)
 | 
			
		||||
    * Add caching for top Balancer V2 pools on startup and during regular intervals (#228)
 | 
			
		||||
    * Tweak compiler settings for smaller sampler bytecode (#229)
 | 
			
		||||
    * Fix Multiplex multihop encoding for ETH buys/sells (#230)
 | 
			
		||||
    * Fix Sampler address override for Ganache (#232)
 | 
			
		||||
 | 
			
		||||
## v6.10.0 - _May 5, 2021_
 | 
			
		||||
 | 
			
		||||
    * Reactivate PancakeSwapV2 and BakerySwap VIP on BSC (#222)
 | 
			
		||||
    * Add LUSD Curve pool (#218)
 | 
			
		||||
    * Fix exchangeProxyGasOverhead for fallback path (#215)
 | 
			
		||||
    * Enable ETH based Curve pools (#220)
 | 
			
		||||
    * Reactivate PancakeSwapV2 and BakerySwap VIP on BSC (#222)
 | 
			
		||||
    * Disable WETH based SnowSwap pools (#220)
 | 
			
		||||
    * PLP now includes a fallback due to observed collisions (#223)
 | 
			
		||||
    * Add Balancer V2 integration (#206)
 | 
			
		||||
    * Re-work the PoolCache for Balancer et al (#226)
 | 
			
		||||
 | 
			
		||||
## 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)
 | 
			
		||||
@@ -21,6 +49,7 @@ CHANGELOG
 | 
			
		||||
## 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_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,11 +6,7 @@
 | 
			
		||||
    "shouldSaveStandardInput": true,
 | 
			
		||||
    "compilerSettings": {
 | 
			
		||||
        "evmVersion": "istanbul",
 | 
			
		||||
        "optimizer": {
 | 
			
		||||
            "enabled": true,
 | 
			
		||||
            "runs": 62500,
 | 
			
		||||
            "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
 | 
			
		||||
        },
 | 
			
		||||
        "optimizer": { "enabled": true, "runs": 200, "details": { "yul": true, "deduplicate": true } },
 | 
			
		||||
        "outputSelection": {
 | 
			
		||||
            "*": {
 | 
			
		||||
                "*": [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										189
									
								
								packages/asset-swapper/contracts/src/BalancerV2Sampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								packages/asset-swapper/contracts/src/BalancerV2Sampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./SamplerUtils.sol";
 | 
			
		||||
 | 
			
		||||
/// @dev Minimal Balancer V2 Vault interface
 | 
			
		||||
///      for documentation refer to https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/vault/interfaces/IVault.sol
 | 
			
		||||
interface IBalancerV2Vault {
 | 
			
		||||
    enum SwapKind { GIVEN_IN, GIVEN_OUT }
 | 
			
		||||
 | 
			
		||||
    struct BatchSwapStep {
 | 
			
		||||
        bytes32 poolId;
 | 
			
		||||
        uint256 assetInIndex;
 | 
			
		||||
        uint256 assetOutIndex;
 | 
			
		||||
        uint256 amount;
 | 
			
		||||
        bytes userData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct FundManagement {
 | 
			
		||||
        address sender;
 | 
			
		||||
        bool fromInternalBalance;
 | 
			
		||||
        address payable recipient;
 | 
			
		||||
        bool toInternalBalance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function queryBatchSwap(
 | 
			
		||||
        SwapKind kind,
 | 
			
		||||
        BatchSwapStep[] calldata swaps,
 | 
			
		||||
        IAsset[] calldata assets,
 | 
			
		||||
        FundManagement calldata funds
 | 
			
		||||
    ) external returns (int256[] memory assetDeltas);
 | 
			
		||||
}
 | 
			
		||||
interface IAsset {
 | 
			
		||||
    // solhint-disable-previous-line no-empty-blocks
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
 | 
			
		||||
    struct BalancerV2PoolInfo {
 | 
			
		||||
        bytes32 poolId;
 | 
			
		||||
        address vault;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from Balancer V2.
 | 
			
		||||
    /// @param poolInfo Struct with pool related data
 | 
			
		||||
    /// @param takerToken Address of the taker token (what to sell).
 | 
			
		||||
    /// @param makerToken Address of the maker token (what to buy).
 | 
			
		||||
    /// @param takerTokenAmounts Taker token sell amount for each sample.
 | 
			
		||||
    /// @return makerTokenAmounts Maker amounts bought at each taker token
 | 
			
		||||
    ///         amount.
 | 
			
		||||
    function sampleSellsFromBalancerV2(
 | 
			
		||||
        BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
        IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault);
 | 
			
		||||
        IAsset[] memory swapAssets = new IAsset[](2);
 | 
			
		||||
        swapAssets[0] = IAsset(takerToken);
 | 
			
		||||
        swapAssets[1] = IAsset(makerToken);
 | 
			
		||||
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        IBalancerV2Vault.FundManagement memory swapFunds =
 | 
			
		||||
            _createSwapFunds();
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            IBalancerV2Vault.BatchSwapStep[] memory swapSteps =
 | 
			
		||||
                _createSwapSteps(poolInfo, takerTokenAmounts[i]);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
                // For sells we specify the takerToken which is what the vault will receive from the trade
 | 
			
		||||
                vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_IN, swapSteps, swapAssets, swapFunds)
 | 
			
		||||
            // amounts represent pool balance deltas from the swap (incoming balance, outgoing balance)
 | 
			
		||||
            returns (int256[] memory amounts) {
 | 
			
		||||
                // Outgoing balance is negative so we need to flip the sign
 | 
			
		||||
                int256 amountOutFromPool = amounts[1] * -1;
 | 
			
		||||
                if (amountOutFromPool <= 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                makerTokenAmounts[i] = uint256(amountOutFromPool);
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample buy quotes from Balancer V2.
 | 
			
		||||
    /// @param poolInfo Struct with pool related data
 | 
			
		||||
    /// @param takerToken Address of the taker token (what to sell).
 | 
			
		||||
    /// @param makerToken Address of the maker token (what to buy).
 | 
			
		||||
    /// @param makerTokenAmounts Maker token buy amount for each sample.
 | 
			
		||||
    /// @return takerTokenAmounts Taker amounts sold at each maker token
 | 
			
		||||
    ///         amount.
 | 
			
		||||
    function sampleBuysFromBalancerV2(
 | 
			
		||||
        BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (uint256[] memory takerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
        IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault);
 | 
			
		||||
        IAsset[] memory swapAssets = new IAsset[](2);
 | 
			
		||||
        swapAssets[0] = IAsset(takerToken);
 | 
			
		||||
        swapAssets[1] = IAsset(makerToken);
 | 
			
		||||
 | 
			
		||||
        uint256 numSamples = makerTokenAmounts.length;
 | 
			
		||||
        takerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        IBalancerV2Vault.FundManagement memory swapFunds =
 | 
			
		||||
            _createSwapFunds();
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            IBalancerV2Vault.BatchSwapStep[] memory swapSteps =
 | 
			
		||||
                _createSwapSteps(poolInfo, makerTokenAmounts[i]);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
                // For buys we specify the makerToken which is what taker will receive from the trade
 | 
			
		||||
                vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_OUT, swapSteps, swapAssets, swapFunds)
 | 
			
		||||
            returns (int256[] memory amounts) {
 | 
			
		||||
                int256 amountIntoPool = amounts[0];
 | 
			
		||||
                if (amountIntoPool <= 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                takerTokenAmounts[i] = uint256(amountIntoPool);
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _createSwapSteps(
 | 
			
		||||
        BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        uint256 amount
 | 
			
		||||
    ) private pure returns (IBalancerV2Vault.BatchSwapStep[] memory) {
 | 
			
		||||
        IBalancerV2Vault.BatchSwapStep[] memory swapSteps =
 | 
			
		||||
            new IBalancerV2Vault.BatchSwapStep[](1);
 | 
			
		||||
        swapSteps[0] = IBalancerV2Vault.BatchSwapStep({
 | 
			
		||||
            poolId: poolInfo.poolId,
 | 
			
		||||
            assetInIndex: 0,
 | 
			
		||||
            assetOutIndex: 1,
 | 
			
		||||
            amount: amount,
 | 
			
		||||
            userData: ""
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return swapSteps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _createSwapFunds()
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (IBalancerV2Vault.FundManagement memory)
 | 
			
		||||
    {
 | 
			
		||||
        return
 | 
			
		||||
            IBalancerV2Vault.FundManagement({
 | 
			
		||||
                sender: address(this),
 | 
			
		||||
                fromInternalBalance: false,
 | 
			
		||||
                recipient: payable(address(this)),
 | 
			
		||||
                toInternalBalance: false
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,16 +22,15 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IBancor.sol";
 | 
			
		||||
 | 
			
		||||
contract DeploymentConstants {}
 | 
			
		||||
contract CompilerHack {}
 | 
			
		||||
 | 
			
		||||
contract BancorSampler is DeploymentConstants
 | 
			
		||||
{
 | 
			
		||||
contract BancorSampler is CompilerHack {
 | 
			
		||||
 | 
			
		||||
    /// @dev Base gas limit for Bancor calls.
 | 
			
		||||
    uint256 constant private BANCOR_CALL_GAS = 300e3; // 300k
 | 
			
		||||
 | 
			
		||||
    struct BancorSamplerOpts {
 | 
			
		||||
        address registry;
 | 
			
		||||
        IBancorRegistry registry;
 | 
			
		||||
        address[][] paths;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -112,7 +111,7 @@ contract BancorSampler is DeploymentConstants
 | 
			
		||||
        view
 | 
			
		||||
        returns (address bancorNetwork, address[] memory path)
 | 
			
		||||
    {
 | 
			
		||||
        bancorNetwork = _getBancorNetwork(opts.registry);
 | 
			
		||||
        bancorNetwork = opts.registry.getAddress(opts.registry.BANCOR_NETWORK());
 | 
			
		||||
        if (opts.paths.length == 0) {
 | 
			
		||||
            return (bancorNetwork, path);
 | 
			
		||||
        }
 | 
			
		||||
@@ -140,13 +139,4 @@ contract BancorSampler is DeploymentConstants
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _getBancorNetwork(address registry)
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (address)
 | 
			
		||||
    {
 | 
			
		||||
        IBancorRegistry registry = IBancorRegistry(registry);
 | 
			
		||||
        return registry.getAddress(registry.BANCOR_NETWORK());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./BalancerSampler.sol";
 | 
			
		||||
import "./BalancerV2Sampler.sol";
 | 
			
		||||
import "./BancorSampler.sol";
 | 
			
		||||
import "./CurveSampler.sol";
 | 
			
		||||
import "./DODOSampler.sol";
 | 
			
		||||
@@ -38,11 +39,13 @@ import "./SmoothySampler.sol";
 | 
			
		||||
import "./TwoHopSampler.sol";
 | 
			
		||||
import "./UniswapSampler.sol";
 | 
			
		||||
import "./UniswapV2Sampler.sol";
 | 
			
		||||
import "./UniswapV3Sampler.sol";
 | 
			
		||||
import "./UtilitySampler.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract ERC20BridgeSampler is
 | 
			
		||||
    BalancerSampler,
 | 
			
		||||
    BalancerV2Sampler,
 | 
			
		||||
    BancorSampler,
 | 
			
		||||
    CurveSampler,
 | 
			
		||||
    DODOSampler,
 | 
			
		||||
@@ -60,6 +63,7 @@ contract ERC20BridgeSampler is
 | 
			
		||||
    TwoHopSampler,
 | 
			
		||||
    UniswapSampler,
 | 
			
		||||
    UniswapV2Sampler,
 | 
			
		||||
    UniswapV3Sampler,
 | 
			
		||||
    UtilitySampler
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@@ -73,7 +77,6 @@ contract ERC20BridgeSampler is
 | 
			
		||||
    /// @return callResults ABI-encoded results data for each call.
 | 
			
		||||
    function batchCall(bytes[] calldata callDatas)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (CallResults[] memory callResults)
 | 
			
		||||
    {
 | 
			
		||||
        callResults = new CallResults[](callDatas.length);
 | 
			
		||||
@@ -82,7 +85,7 @@ contract ERC20BridgeSampler is
 | 
			
		||||
            if (callDatas[i].length == 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            (callResults[i].success, callResults[i].data) = address(this).staticcall(callDatas[i]);
 | 
			
		||||
            (callResults[i].success, callResults[i].data) = address(this).call(callDatas[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										313
									
								
								packages/asset-swapper/contracts/src/UniswapV3Sampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								packages/asset-swapper/contracts/src/UniswapV3Sampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,313 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
 | 
			
		||||
interface IUniswapV3Quoter {
 | 
			
		||||
    function factory()
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (IUniswapV3Factory factory);
 | 
			
		||||
    function quoteExactInput(bytes memory path, uint256 amountIn)
 | 
			
		||||
        external
 | 
			
		||||
        returns (uint256 amountOut);
 | 
			
		||||
    function quoteExactOutput(bytes memory path, uint256 amountOut)
 | 
			
		||||
        external
 | 
			
		||||
        returns (uint256 amountIn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IUniswapV3Factory {
 | 
			
		||||
    function getPool(IERC20TokenV06 a, IERC20TokenV06 b, uint24 fee)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (IUniswapV3Pool pool);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IUniswapV3Pool {
 | 
			
		||||
    function token0() external view returns (IERC20TokenV06);
 | 
			
		||||
    function token1() external view returns (IERC20TokenV06);
 | 
			
		||||
    function fee() external view returns (uint24);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract UniswapV3Sampler
 | 
			
		||||
{
 | 
			
		||||
    /// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
 | 
			
		||||
    uint256 constant private QUOTE_GAS = 300e3;
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from UniswapV3.
 | 
			
		||||
    /// @param quoter UniswapV3 Quoter contract.
 | 
			
		||||
    /// @param path Token route. Should be takerToken -> makerToken
 | 
			
		||||
    /// @param takerTokenAmounts Taker token sell amount for each sample.
 | 
			
		||||
    /// @return makerTokenAmounts Maker amounts bought at each taker token
 | 
			
		||||
    ///         amount.
 | 
			
		||||
    /// @return uniswapPaths The encoded uniswap path for each sample.
 | 
			
		||||
    function sampleSellsFromUniswapV3(
 | 
			
		||||
        IUniswapV3Quoter quoter,
 | 
			
		||||
        IERC20TokenV06[] memory path,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (
 | 
			
		||||
            uint256[] memory makerTokenAmounts,
 | 
			
		||||
            bytes[] memory uniswapPaths
 | 
			
		||||
        )
 | 
			
		||||
    {
 | 
			
		||||
        IUniswapV3Pool[][] memory poolPaths =
 | 
			
		||||
            _getValidPoolPaths(quoter.factory(), path, 0);
 | 
			
		||||
 | 
			
		||||
        makerTokenAmounts = new uint256[](takerTokenAmounts.length);
 | 
			
		||||
        uniswapPaths = new bytes[](takerTokenAmounts.length);
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < takerTokenAmounts.length; ++i) {
 | 
			
		||||
            // Pick the best result from all the paths.
 | 
			
		||||
            bytes memory topUniswapPath;
 | 
			
		||||
            uint256 topBuyAmount = 0;
 | 
			
		||||
            for (uint256 j = 0; j < poolPaths.length; ++j) {
 | 
			
		||||
                bytes memory uniswapPath = _toUniswapPath(path, poolPaths[j]);
 | 
			
		||||
                try
 | 
			
		||||
                    quoter.quoteExactInput
 | 
			
		||||
                        { gas: QUOTE_GAS }
 | 
			
		||||
                        (uniswapPath, takerTokenAmounts[i])
 | 
			
		||||
                        returns (uint256 buyAmount)
 | 
			
		||||
                {
 | 
			
		||||
                    if (topBuyAmount <= buyAmount) {
 | 
			
		||||
                        topBuyAmount = buyAmount;
 | 
			
		||||
                        topUniswapPath = uniswapPath;
 | 
			
		||||
                    }
 | 
			
		||||
                } catch { }
 | 
			
		||||
            }
 | 
			
		||||
            // Break early if we can't complete the buys.
 | 
			
		||||
            if (topBuyAmount == 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            makerTokenAmounts[i] = topBuyAmount;
 | 
			
		||||
            uniswapPaths[i] = topUniswapPath;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample buy quotes from UniswapV3.
 | 
			
		||||
    /// @param quoter UniswapV3 Quoter contract.
 | 
			
		||||
    /// @param path Token route. Should be takerToken -> makerToken.
 | 
			
		||||
    /// @param makerTokenAmounts Maker token buy amount for each sample.
 | 
			
		||||
    /// @return takerTokenAmounts Taker amounts sold at each maker token
 | 
			
		||||
    ///         amount.
 | 
			
		||||
    /// @return uniswapPaths The encoded uniswap path for each sample.
 | 
			
		||||
    function sampleBuysFromUniswapV3(
 | 
			
		||||
        IUniswapV3Quoter quoter,
 | 
			
		||||
        IERC20TokenV06[] memory path,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (
 | 
			
		||||
            uint256[] memory takerTokenAmounts,
 | 
			
		||||
            bytes[] memory uniswapPaths
 | 
			
		||||
        )
 | 
			
		||||
    {
 | 
			
		||||
        IUniswapV3Pool[][] memory poolPaths =
 | 
			
		||||
            _getValidPoolPaths(quoter.factory(), path, 0);
 | 
			
		||||
        IERC20TokenV06[] memory reversedPath = _reverseTokenPath(path);
 | 
			
		||||
 | 
			
		||||
        takerTokenAmounts = new uint256[](makerTokenAmounts.length);
 | 
			
		||||
        uniswapPaths = new bytes[](makerTokenAmounts.length);
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < makerTokenAmounts.length; ++i) {
 | 
			
		||||
            // Pick the best result from all the paths.
 | 
			
		||||
            bytes memory topUniswapPath;
 | 
			
		||||
            uint256 topSellAmount = 0;
 | 
			
		||||
            for (uint256 j = 0; j < poolPaths.length; ++j) {
 | 
			
		||||
                // quoter requires path to be reversed for buys.
 | 
			
		||||
                bytes memory uniswapPath = _toUniswapPath(
 | 
			
		||||
                    reversedPath,
 | 
			
		||||
                    _reversePoolPath(poolPaths[j])
 | 
			
		||||
                );
 | 
			
		||||
                try
 | 
			
		||||
                    quoter.quoteExactOutput
 | 
			
		||||
                        { gas: QUOTE_GAS }
 | 
			
		||||
                        (uniswapPath, makerTokenAmounts[i])
 | 
			
		||||
                        returns (uint256 sellAmount)
 | 
			
		||||
                {
 | 
			
		||||
                    if (topSellAmount == 0 || topSellAmount >= sellAmount) {
 | 
			
		||||
                        topSellAmount = sellAmount;
 | 
			
		||||
                        // But the output path should still be encoded for sells.
 | 
			
		||||
                        topUniswapPath = _toUniswapPath(path, poolPaths[j]);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch {}
 | 
			
		||||
            }
 | 
			
		||||
            // Break early if we can't complete the buys.
 | 
			
		||||
            if (topSellAmount == 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            takerTokenAmounts[i] = topSellAmount;
 | 
			
		||||
            uniswapPaths[i] = topUniswapPath;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _getValidPoolPaths(
 | 
			
		||||
        IUniswapV3Factory factory,
 | 
			
		||||
        IERC20TokenV06[] memory tokenPath,
 | 
			
		||||
        uint256 startIndex
 | 
			
		||||
    )
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (IUniswapV3Pool[][] memory poolPaths)
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            tokenPath.length - startIndex >= 2,
 | 
			
		||||
            "UniswapV3Sampler/tokenPath too short"
 | 
			
		||||
        );
 | 
			
		||||
        uint24[3] memory validPoolFees = [
 | 
			
		||||
            // The launch pool fees. Could get hairier if they add more.
 | 
			
		||||
            uint24(0.0005e6),
 | 
			
		||||
            uint24(0.003e6),
 | 
			
		||||
            uint24(0.01e6)
 | 
			
		||||
        ];
 | 
			
		||||
        IUniswapV3Pool[] memory validPools =
 | 
			
		||||
            new IUniswapV3Pool[](validPoolFees.length);
 | 
			
		||||
        uint256 numValidPools = 0;
 | 
			
		||||
        {
 | 
			
		||||
            IERC20TokenV06 inputToken = tokenPath[startIndex];
 | 
			
		||||
            IERC20TokenV06 outputToken = tokenPath[startIndex + 1];
 | 
			
		||||
            for (uint256 i = 0; i < validPoolFees.length; ++i) {
 | 
			
		||||
                IUniswapV3Pool pool =
 | 
			
		||||
                factory.getPool(inputToken, outputToken, validPoolFees[i]);
 | 
			
		||||
                if (_isValidPool(pool)) {
 | 
			
		||||
                    validPools[numValidPools++] = pool;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (numValidPools == 0) {
 | 
			
		||||
            // No valid pools for this hop.
 | 
			
		||||
            return poolPaths;
 | 
			
		||||
        }
 | 
			
		||||
        if (startIndex + 2 == tokenPath.length) {
 | 
			
		||||
            // End of path.
 | 
			
		||||
            poolPaths = new IUniswapV3Pool[][](numValidPools);
 | 
			
		||||
            for (uint256 i = 0; i < numValidPools; ++i) {
 | 
			
		||||
                poolPaths[i] = new IUniswapV3Pool[](1);
 | 
			
		||||
                poolPaths[i][0] = validPools[i];
 | 
			
		||||
            }
 | 
			
		||||
            return poolPaths;
 | 
			
		||||
        }
 | 
			
		||||
        // Get paths for subsequent hops.
 | 
			
		||||
        IUniswapV3Pool[][] memory subsequentPoolPaths =
 | 
			
		||||
            _getValidPoolPaths(factory, tokenPath, startIndex + 1);
 | 
			
		||||
        if (subsequentPoolPaths.length == 0) {
 | 
			
		||||
            // Could not complete the path.
 | 
			
		||||
            return poolPaths;
 | 
			
		||||
        }
 | 
			
		||||
        // Combine our pools with the next hop paths.
 | 
			
		||||
        poolPaths = new IUniswapV3Pool[][](
 | 
			
		||||
            numValidPools * subsequentPoolPaths.length
 | 
			
		||||
        );
 | 
			
		||||
        for (uint256 i = 0; i < numValidPools; ++i) {
 | 
			
		||||
            for (uint256 j = 0; j < subsequentPoolPaths.length; ++j) {
 | 
			
		||||
                uint256 o = i * subsequentPoolPaths.length + j;
 | 
			
		||||
                // Prepend pool to the subsequent path.
 | 
			
		||||
                poolPaths[o] =
 | 
			
		||||
                    new IUniswapV3Pool[](1 + subsequentPoolPaths[j].length);
 | 
			
		||||
                poolPaths[o][0] = validPools[i];
 | 
			
		||||
                for (uint256 k = 0; k < subsequentPoolPaths[j].length; ++k) {
 | 
			
		||||
                    poolPaths[o][1 + k] = subsequentPoolPaths[j][k];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return poolPaths;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _reverseTokenPath(IERC20TokenV06[] memory tokenPath)
 | 
			
		||||
        private
 | 
			
		||||
        returns (IERC20TokenV06[] memory reversed)
 | 
			
		||||
    {
 | 
			
		||||
        reversed = new IERC20TokenV06[](tokenPath.length);
 | 
			
		||||
        for (uint256 i = 0; i < tokenPath.length; ++i) {
 | 
			
		||||
            reversed[i] = tokenPath[tokenPath.length - i - 1];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _reversePoolPath(IUniswapV3Pool[] memory poolPath)
 | 
			
		||||
        private
 | 
			
		||||
        returns (IUniswapV3Pool[] memory reversed)
 | 
			
		||||
    {
 | 
			
		||||
        reversed = new IUniswapV3Pool[](poolPath.length);
 | 
			
		||||
        for (uint256 i = 0; i < poolPath.length; ++i) {
 | 
			
		||||
            reversed[i] = poolPath[poolPath.length - i - 1];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _isValidPool(IUniswapV3Pool pool)
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (bool isValid)
 | 
			
		||||
    {
 | 
			
		||||
        // Check if it has been deployed.
 | 
			
		||||
        {
 | 
			
		||||
            uint256 codeSize;
 | 
			
		||||
            assembly {
 | 
			
		||||
                codeSize := extcodesize(pool)
 | 
			
		||||
            }
 | 
			
		||||
            if (codeSize == 0) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Must have a balance of both tokens.
 | 
			
		||||
        if (pool.token0().balanceOf(address(pool)) == 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (pool.token1().balanceOf(address(pool)) == 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _toUniswapPath(
 | 
			
		||||
        IERC20TokenV06[] memory tokenPath,
 | 
			
		||||
        IUniswapV3Pool[] memory poolPath
 | 
			
		||||
    )
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes memory uniswapPath)
 | 
			
		||||
    {
 | 
			
		||||
        require(
 | 
			
		||||
            tokenPath.length >= 2 && tokenPath.length == poolPath.length + 1,
 | 
			
		||||
            "UniswapV3Sampler/invalid path lengths"
 | 
			
		||||
        );
 | 
			
		||||
        // Uniswap paths are tightly packed as:
 | 
			
		||||
        // [token0, token0token1PairFee, token1, token1Token2PairFee, token2, ...]
 | 
			
		||||
        uniswapPath = new bytes(tokenPath.length * 20 + poolPath.length * 3);
 | 
			
		||||
        uint256 o;
 | 
			
		||||
        assembly { o := add(uniswapPath, 32) }
 | 
			
		||||
        for (uint256 i = 0; i < tokenPath.length; ++i) {
 | 
			
		||||
            if (i > 0) {
 | 
			
		||||
                uint24 poolFee = poolPath[i - 1].fee();
 | 
			
		||||
                assembly {
 | 
			
		||||
                    mstore(o, shl(232, poolFee))
 | 
			
		||||
                    o := add(o, 3)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            IERC20TokenV06 token = tokenPath[i];
 | 
			
		||||
            assembly {
 | 
			
		||||
                mstore(o, shl(96, token))
 | 
			
		||||
                o := add(o, 20)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/asset-swapper",
 | 
			
		||||
    "version": "6.8.0",
 | 
			
		||||
    "version": "6.11.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -33,12 +33,13 @@
 | 
			
		||||
        "generate_contract_wrappers": "abi-gen --debug --abis  ${npm_package_config_abis} --output test/generated-wrappers --backend ethers",
 | 
			
		||||
        "contracts:gen": "contracts-gen generate",
 | 
			
		||||
        "contracts:copy": "contracts-gen copy",
 | 
			
		||||
        "publish:private": "yarn build && gitpkg publish"
 | 
			
		||||
        "publish:private": "yarn build && gitpkg publish",
 | 
			
		||||
        "sampler-size": "jq .compilerOutput.evm.deployedBytecode.object  -- test/generated-artifacts/ERC20BridgeSampler.json | echo $(( $(wc -c) / 2 - 1 ))"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
 | 
			
		||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BancorSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|Eth2DaiSampler|FakeTaker|IBalancer|IBancor|ICurve|IEth2Dai|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UtilitySampler).json",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2Sampler|BancorSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|Eth2DaiSampler|FakeTaker|IBalancer|IBancor|ICurve|IEth2Dai|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
 | 
			
		||||
        "postpublish": {
 | 
			
		||||
            "assets": []
 | 
			
		||||
        }
 | 
			
		||||
@@ -57,20 +58,20 @@
 | 
			
		||||
        "registry": "git@github.com:0xProject/gitpkg-registry.git"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^3.0.26",
 | 
			
		||||
        "@0x/assert": "^3.0.27",
 | 
			
		||||
        "@0x/base-contract": "^6.4.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.0.0",
 | 
			
		||||
        "@0x/contract-wrappers": "^13.16.0",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.7",
 | 
			
		||||
        "@0x/contracts-zero-ex": "^0.22.1",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.6",
 | 
			
		||||
        "@0x/json-schemas": "^6.1.2",
 | 
			
		||||
        "@0x/protocol-utils": "^1.5.1",
 | 
			
		||||
        "@0x/contract-addresses": "^6.1.0",
 | 
			
		||||
        "@0x/contract-wrappers": "^13.16.1",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.8",
 | 
			
		||||
        "@0x/contracts-zero-ex": "^0.23.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.7",
 | 
			
		||||
        "@0x/json-schemas": "^6.1.3",
 | 
			
		||||
        "@0x/protocol-utils": "^1.6.0",
 | 
			
		||||
        "@0x/quote-server": "^5.0.0",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.0",
 | 
			
		||||
        "@0x/utils": "^6.4.2",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.2",
 | 
			
		||||
        "@0x/utils": "^6.4.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.5.3",
 | 
			
		||||
        "@balancer-labs/sor": "0.3.2",
 | 
			
		||||
        "@bancor/sdk": "0.2.9",
 | 
			
		||||
        "@ethersproject/abi": "^5.0.1",
 | 
			
		||||
@@ -85,21 +86,23 @@
 | 
			
		||||
        "ethereum-types": "^3.5.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10",
 | 
			
		||||
        "fast-abi": "^0.0.2",
 | 
			
		||||
        "graphql": "^15.4.0",
 | 
			
		||||
        "graphql-request": "^3.4.0",
 | 
			
		||||
        "heartbeats": "^5.0.1",
 | 
			
		||||
        "lodash": "^4.17.11"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@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/contracts-asset-proxy": "^3.7.11",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.30",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.29",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.38",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.0",
 | 
			
		||||
        "@0x/contracts-utils": "^4.7.8",
 | 
			
		||||
        "@0x/mesh-rpc-client": "^9.4.2",
 | 
			
		||||
        "@0x/migrations": "^8.0.3",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.2",
 | 
			
		||||
        "@0x/subproviders": "^6.5.2",
 | 
			
		||||
        "@0x/migrations": "^8.0.6",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.3",
 | 
			
		||||
        "@0x/subproviders": "^6.5.3",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.3",
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,7 @@ export {
 | 
			
		||||
    SOURCE_FLAGS,
 | 
			
		||||
    BUY_SOURCE_FILTER_BY_CHAIN_ID,
 | 
			
		||||
    SELL_SOURCE_FILTER_BY_CHAIN_ID,
 | 
			
		||||
    NATIVE_FEE_TOKEN_BY_CHAIN_ID,
 | 
			
		||||
} from './utils/market_operation_utils/constants';
 | 
			
		||||
export {
 | 
			
		||||
    Parameters,
 | 
			
		||||
@@ -160,6 +161,7 @@ export {
 | 
			
		||||
    NativeRfqOrderQuoteReportEntry,
 | 
			
		||||
    QuoteReport,
 | 
			
		||||
    QuoteReportEntry,
 | 
			
		||||
    PriceComparisonsReport,
 | 
			
		||||
} from './utils/quote_report_generator';
 | 
			
		||||
export { QuoteRequestor } from './utils/quote_requestor';
 | 
			
		||||
export { ERC20BridgeSamplerContract, BalanceCheckerContract, FakeTakerContract } from './wrappers';
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,7 @@ import {
 | 
			
		||||
    FillQuoteTransformerSide,
 | 
			
		||||
    findTransformerNonce,
 | 
			
		||||
} from '@0x/protocol-utils';
 | 
			
		||||
import { BigNumber, providerUtils } from '@0x/utils';
 | 
			
		||||
import { SupportedProvider, ZeroExProvider } from '@0x/web3-wrapper';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { constants, POSITIVE_SLIPPAGE_FEE_TRANSFORMER_GAS } from '../constants';
 | 
			
		||||
@@ -65,15 +64,26 @@ 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];
 | 
			
		||||
const DUMMY_WETH_CONTRACT = new WETH9Contract(NULL_ADDRESS, {
 | 
			
		||||
 | 
			
		||||
// 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 FAKE_PROVIDER: any = {
 | 
			
		||||
    sendAsync(): void {
 | 
			
		||||
        return;
 | 
			
		||||
    },
 | 
			
		||||
} as any);
 | 
			
		||||
};
 | 
			
		||||
const DUMMY_WETH_CONTRACT = new WETH9Contract(NULL_ADDRESS, FAKE_PROVIDER);
 | 
			
		||||
 | 
			
		||||
export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
    public readonly provider: ZeroExProvider;
 | 
			
		||||
    public readonly chainId: ChainId;
 | 
			
		||||
    public readonly transformerNonces: {
 | 
			
		||||
        wethTransformer: number;
 | 
			
		||||
@@ -86,19 +96,13 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
    private readonly _exchangeProxy: IZeroExContract;
 | 
			
		||||
    private readonly _multiplex: MultiplexFeatureContract;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        supportedProvider: SupportedProvider,
 | 
			
		||||
        public readonly contractAddresses: ContractAddresses,
 | 
			
		||||
        options: Partial<SwapQuoteConsumerOpts> = {},
 | 
			
		||||
    ) {
 | 
			
		||||
    constructor(public readonly contractAddresses: ContractAddresses, options: Partial<SwapQuoteConsumerOpts> = {}) {
 | 
			
		||||
        const { chainId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
 | 
			
		||||
        assert.isNumber('chainId', chainId);
 | 
			
		||||
        const provider = providerUtils.standardizeOrThrow(supportedProvider);
 | 
			
		||||
        this.provider = provider;
 | 
			
		||||
        this.chainId = chainId;
 | 
			
		||||
        this.contractAddresses = contractAddresses;
 | 
			
		||||
        this._exchangeProxy = new IZeroExContract(contractAddresses.exchangeProxy, supportedProvider);
 | 
			
		||||
        this._multiplex = new MultiplexFeatureContract(contractAddresses.exchangeProxy, supportedProvider);
 | 
			
		||||
        this._exchangeProxy = new IZeroExContract(contractAddresses.exchangeProxy, FAKE_PROVIDER);
 | 
			
		||||
        this._multiplex = new MultiplexFeatureContract(contractAddresses.exchangeProxy, FAKE_PROVIDER);
 | 
			
		||||
        this.transformerNonces = {
 | 
			
		||||
            wethTransformer: findTransformerNonce(
 | 
			
		||||
                contractAddresses.transformers.wethTransformer,
 | 
			
		||||
@@ -186,8 +190,13 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
            this.chainId === ChainId.BSC &&
 | 
			
		||||
            isDirectSwapCompatible(quote, optsWithDefaults, [
 | 
			
		||||
                ERC20BridgeSource.PancakeSwap,
 | 
			
		||||
                ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
                ERC20BridgeSource.BakerySwap,
 | 
			
		||||
                ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                ERC20BridgeSource.ApeSwap,
 | 
			
		||||
                ERC20BridgeSource.CafeSwap,
 | 
			
		||||
                ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
                ERC20BridgeSource.JulSwap,
 | 
			
		||||
            ])
 | 
			
		||||
        ) {
 | 
			
		||||
            const source = slippedOrders[0].source;
 | 
			
		||||
@@ -243,7 +252,11 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
 | 
			
		||||
        if (
 | 
			
		||||
            this.chainId === ChainId.Mainnet &&
 | 
			
		||||
            isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve, ERC20BridgeSource.Swerve])
 | 
			
		||||
            isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve, ERC20BridgeSource.Swerve]) &&
 | 
			
		||||
            // Curve VIP cannot currently support WETH buy/sell as the functionality needs to WITHDRAW or DEPOSIT
 | 
			
		||||
            // into WETH prior/post the trade.
 | 
			
		||||
            // ETH buy/sell is supported
 | 
			
		||||
            ![sellToken, buyToken].includes(NATIVE_FEE_TOKEN_BY_CHAIN_ID[ChainId.Mainnet])
 | 
			
		||||
        ) {
 | 
			
		||||
            const fillData = slippedOrders[0].fills[0].fillData as CurveFillData;
 | 
			
		||||
            return {
 | 
			
		||||
@@ -552,14 +565,17 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
 | 
			
		||||
    private _encodeMultiplexMultiHopFillCalldata(quote: SwapQuote, opts: ExchangeProxyContractOpts): string {
 | 
			
		||||
        const wrappedMultiHopCalls = [];
 | 
			
		||||
        const tokens: string[] = [];
 | 
			
		||||
        if (opts.isFromETH) {
 | 
			
		||||
            wrappedMultiHopCalls.push({
 | 
			
		||||
                selector: DUMMY_WETH_CONTRACT.getSelector('deposit'),
 | 
			
		||||
                data: NULL_BYTES,
 | 
			
		||||
            });
 | 
			
		||||
            tokens.push(ETH_TOKEN_ADDRESS);
 | 
			
		||||
        }
 | 
			
		||||
        const [firstHopOrder, secondHopOrder] = quote.orders;
 | 
			
		||||
        const intermediateToken = firstHopOrder.makerToken;
 | 
			
		||||
        tokens.push(quote.takerToken, intermediateToken, quote.makerToken);
 | 
			
		||||
        for (const order of [firstHopOrder, secondHopOrder]) {
 | 
			
		||||
            switch (order.source) {
 | 
			
		||||
                case ERC20BridgeSource.UniswapV2:
 | 
			
		||||
@@ -594,11 +610,12 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
                selector: DUMMY_WETH_CONTRACT.getSelector('withdraw'),
 | 
			
		||||
                data: NULL_BYTES,
 | 
			
		||||
            });
 | 
			
		||||
            tokens.push(ETH_TOKEN_ADDRESS);
 | 
			
		||||
        }
 | 
			
		||||
        return this._exchangeProxy
 | 
			
		||||
            .multiHopFill(
 | 
			
		||||
                {
 | 
			
		||||
                    tokens: [quote.takerToken, intermediateToken, quote.makerToken],
 | 
			
		||||
                    tokens,
 | 
			
		||||
                    sellAmount: quote.worstCaseQuoteInfo.totalTakerAmount,
 | 
			
		||||
                    calls: wrappedMultiHopCalls,
 | 
			
		||||
                },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
import { ContractAddresses, getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
 | 
			
		||||
import { providerUtils } from '@0x/utils';
 | 
			
		||||
import { SupportedProvider, ZeroExProvider } from '@0x/web3-wrapper';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { constants } from '../constants';
 | 
			
		||||
@@ -17,32 +15,22 @@ import { assert } from '../utils/assert';
 | 
			
		||||
import { ExchangeProxySwapQuoteConsumer } from './exchange_proxy_swap_quote_consumer';
 | 
			
		||||
 | 
			
		||||
export class SwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
    public readonly provider: ZeroExProvider;
 | 
			
		||||
    public readonly chainId: number;
 | 
			
		||||
 | 
			
		||||
    private readonly _contractAddresses: ContractAddresses;
 | 
			
		||||
    private readonly _exchangeProxyConsumer: ExchangeProxySwapQuoteConsumer;
 | 
			
		||||
 | 
			
		||||
    public static getSwapQuoteConsumer(
 | 
			
		||||
        supportedProvider: SupportedProvider,
 | 
			
		||||
        options: Partial<SwapQuoteConsumerOpts> = {},
 | 
			
		||||
    ): SwapQuoteConsumer {
 | 
			
		||||
        return new SwapQuoteConsumer(supportedProvider, options);
 | 
			
		||||
    public static getSwapQuoteConsumer(options: Partial<SwapQuoteConsumerOpts> = {}): SwapQuoteConsumer {
 | 
			
		||||
        return new SwapQuoteConsumer(options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor(supportedProvider: SupportedProvider, options: Partial<SwapQuoteConsumerOpts> = {}) {
 | 
			
		||||
    constructor(options: Partial<SwapQuoteConsumerOpts> = {}) {
 | 
			
		||||
        const { chainId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
 | 
			
		||||
        assert.isNumber('chainId', chainId);
 | 
			
		||||
 | 
			
		||||
        const provider = providerUtils.standardizeOrThrow(supportedProvider);
 | 
			
		||||
        this.provider = provider;
 | 
			
		||||
        this.chainId = chainId;
 | 
			
		||||
        this._contractAddresses = options.contractAddresses || getContractAddressesForChainOrThrow(chainId);
 | 
			
		||||
        this._exchangeProxyConsumer = new ExchangeProxySwapQuoteConsumer(
 | 
			
		||||
            supportedProvider,
 | 
			
		||||
            this._contractAddresses,
 | 
			
		||||
            options,
 | 
			
		||||
        );
 | 
			
		||||
        this._exchangeProxyConsumer = new ExchangeProxySwapQuoteConsumer(this._contractAddresses, options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ import {
 | 
			
		||||
import { assert } from './utils/assert';
 | 
			
		||||
import { MarketOperationUtils } from './utils/market_operation_utils';
 | 
			
		||||
import { BancorService } from './utils/market_operation_utils/bancor_service';
 | 
			
		||||
import { SOURCE_FLAGS, ZERO_AMOUNT } from './utils/market_operation_utils/constants';
 | 
			
		||||
import { SAMPLER_ADDRESS, SOURCE_FLAGS, ZERO_AMOUNT } from './utils/market_operation_utils/constants';
 | 
			
		||||
import { DexOrderSampler } from './utils/market_operation_utils/sampler';
 | 
			
		||||
import { SourceFilters } from './utils/market_operation_utils/source_filters';
 | 
			
		||||
import {
 | 
			
		||||
@@ -93,7 +93,7 @@ export class SwapQuoter {
 | 
			
		||||
            rfqt,
 | 
			
		||||
            tokenAdjacencyGraph,
 | 
			
		||||
            liquidityProviderRegistry,
 | 
			
		||||
        } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
 | 
			
		||||
        } = { ...constants.DEFAULT_SWAP_QUOTER_OPTS, ...options };
 | 
			
		||||
        const provider = providerUtils.standardizeOrThrow(supportedProvider);
 | 
			
		||||
        assert.isValidOrderbook('orderbook', orderbook);
 | 
			
		||||
        assert.isNumber('chainId', chainId);
 | 
			
		||||
@@ -114,9 +114,11 @@ export class SwapQuoter {
 | 
			
		||||
        );
 | 
			
		||||
        // Allow the sampler bytecode to be overwritten using geths override functionality
 | 
			
		||||
        const samplerBytecode = _.get(artifacts.ERC20BridgeSampler, 'compilerOutput.evm.deployedBytecode.object');
 | 
			
		||||
        // Allow address of the Sampler to be overridden, i.e in Ganache where overrides do not work
 | 
			
		||||
        const samplerAddress = (options.samplerOverrides && options.samplerOverrides.to) || SAMPLER_ADDRESS;
 | 
			
		||||
        const defaultCodeOverrides = samplerBytecode
 | 
			
		||||
            ? {
 | 
			
		||||
                  [this._contractAddresses.erc20BridgeSampler]: { code: samplerBytecode },
 | 
			
		||||
                  [samplerAddress]: { code: samplerBytecode },
 | 
			
		||||
              }
 | 
			
		||||
            : {};
 | 
			
		||||
        const samplerOverrides = _.assign(
 | 
			
		||||
@@ -125,7 +127,7 @@ export class SwapQuoter {
 | 
			
		||||
        );
 | 
			
		||||
        const fastAbi = new FastABI(ERC20BridgeSamplerContract.ABI() as MethodAbi[]);
 | 
			
		||||
        const samplerContract = new ERC20BridgeSamplerContract(
 | 
			
		||||
            this._contractAddresses.erc20BridgeSampler,
 | 
			
		||||
            samplerAddress,
 | 
			
		||||
            this.provider,
 | 
			
		||||
            {
 | 
			
		||||
                gas: samplerGasLimit,
 | 
			
		||||
@@ -143,8 +145,7 @@ export class SwapQuoter {
 | 
			
		||||
                this.chainId,
 | 
			
		||||
                samplerContract,
 | 
			
		||||
                samplerOverrides,
 | 
			
		||||
                undefined, // balancer pool cache
 | 
			
		||||
                undefined, // cream pool cache
 | 
			
		||||
                undefined, // pools caches for balancer and cream
 | 
			
		||||
                tokenAdjacencyGraph,
 | 
			
		||||
                liquidityProviderRegistry,
 | 
			
		||||
                this.chainId === ChainId.Mainnet // Enable Bancor only on Mainnet
 | 
			
		||||
@@ -496,7 +497,14 @@ function createSwapQuote(
 | 
			
		||||
    gasSchedule: FeeSchedule,
 | 
			
		||||
    slippage: number,
 | 
			
		||||
): SwapQuote {
 | 
			
		||||
    const { optimizedOrders, quoteReport, sourceFlags, takerAmountPerEth, makerAmountPerEth } = optimizerResult;
 | 
			
		||||
    const {
 | 
			
		||||
        optimizedOrders,
 | 
			
		||||
        quoteReport,
 | 
			
		||||
        sourceFlags,
 | 
			
		||||
        takerAmountPerEth,
 | 
			
		||||
        makerAmountPerEth,
 | 
			
		||||
        priceComparisonsReport,
 | 
			
		||||
    } = optimizerResult;
 | 
			
		||||
    const isTwoHop = sourceFlags === SOURCE_FLAGS[ERC20BridgeSource.MultiHop];
 | 
			
		||||
 | 
			
		||||
    // Calculate quote info
 | 
			
		||||
@@ -520,6 +528,7 @@ function createSwapQuote(
 | 
			
		||||
        makerAmountPerEth,
 | 
			
		||||
        quoteReport,
 | 
			
		||||
        isTwoHop,
 | 
			
		||||
        priceComparisonsReport,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (operation === MarketOperation.Buy) {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ import {
 | 
			
		||||
    OptimizedMarketOrder,
 | 
			
		||||
    TokenAdjacencyGraph,
 | 
			
		||||
} from './utils/market_operation_utils/types';
 | 
			
		||||
import { QuoteReport } from './utils/quote_report_generator';
 | 
			
		||||
import { PriceComparisonsReport, QuoteReport } from './utils/quote_report_generator';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * expiryBufferMs: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m).
 | 
			
		||||
@@ -169,6 +169,7 @@ export interface SwapQuoteBase {
 | 
			
		||||
    worstCaseQuoteInfo: SwapQuoteInfo;
 | 
			
		||||
    sourceBreakdown: SwapQuoteOrdersBreakdown;
 | 
			
		||||
    quoteReport?: QuoteReport;
 | 
			
		||||
    priceComparisonsReport?: PriceComparisonsReport;
 | 
			
		||||
    isTwoHop: boolean;
 | 
			
		||||
    makerTokenDecimals: number;
 | 
			
		||||
    takerTokenDecimals: number;
 | 
			
		||||
@@ -385,6 +386,7 @@ export interface AltMockedRfqQuoteResponse {
 | 
			
		||||
export interface SamplerOverrides {
 | 
			
		||||
    overrides: GethCallOverrides;
 | 
			
		||||
    block: BlockParam;
 | 
			
		||||
    to?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface SamplerCallResult {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,192 +0,0 @@
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from '@balancer-labs/sor';
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_SUBGRAPH_URL, BALANCER_TOP_POOLS_FETCHED } from './constants';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:boolean-naming
 | 
			
		||||
 | 
			
		||||
interface CacheValue {
 | 
			
		||||
    timestamp: number;
 | 
			
		||||
    pools: Pool[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tslint:disable:custom-no-magic-numbers
 | 
			
		||||
const FIVE_SECONDS_MS = 5 * 1000;
 | 
			
		||||
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
 | 
			
		||||
const DEFAULT_TIMEOUT_MS = 1000;
 | 
			
		||||
// tslint:enable:custom-no-magic-numbers
 | 
			
		||||
 | 
			
		||||
interface BalancerPoolResponse {
 | 
			
		||||
    id: string;
 | 
			
		||||
    swapFee: string;
 | 
			
		||||
    tokens: Array<{ address: string; decimals: number; balance: string }>;
 | 
			
		||||
    tokensList: string[];
 | 
			
		||||
    totalWeight: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class BalancerPoolsCache {
 | 
			
		||||
    constructor(
 | 
			
		||||
        private readonly _cache: { [key: string]: CacheValue } = {},
 | 
			
		||||
        private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
 | 
			
		||||
        private readonly subgraphUrl: string = BALANCER_SUBGRAPH_URL,
 | 
			
		||||
        private readonly topPoolsFetched: number = BALANCER_TOP_POOLS_FETCHED,
 | 
			
		||||
    ) {
 | 
			
		||||
        void this._loadTopPoolsAsync();
 | 
			
		||||
        // Reload the top pools every 12 hours
 | 
			
		||||
        setInterval(async () => void this._loadTopPoolsAsync(), ONE_DAY_MS / 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async getPoolsForPairAsync(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        timeoutMs: number = DEFAULT_TIMEOUT_MS,
 | 
			
		||||
    ): Promise<Pool[]> {
 | 
			
		||||
        const timeout = new Promise<Pool[]>(resolve => setTimeout(resolve, timeoutMs, []));
 | 
			
		||||
        return Promise.race([this._getPoolsForPairAsync(takerToken, makerToken), timeout]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getCachedPoolAddressesForPair(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        cacheExpiryMs?: number,
 | 
			
		||||
    ): string[] | undefined {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        if (cacheExpiryMs === undefined) {
 | 
			
		||||
            return value === undefined ? [] : value.pools.map(pool => pool.id);
 | 
			
		||||
        }
 | 
			
		||||
        const minTimestamp = Date.now() - cacheExpiryMs;
 | 
			
		||||
        if (value === undefined || value.timestamp < minTimestamp) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        } else {
 | 
			
		||||
            return value.pools.map(pool => pool.id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public howToSampleBalancer(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        isAllowedSource: boolean,
 | 
			
		||||
    ): { onChain: boolean; offChain: boolean } {
 | 
			
		||||
        // If Balancer is excluded as a source, do not sample.
 | 
			
		||||
        if (!isAllowedSource) {
 | 
			
		||||
            return { onChain: false, offChain: false };
 | 
			
		||||
        }
 | 
			
		||||
        const cachedBalancerPools = this.getCachedPoolAddressesForPair(takerToken, makerToken, ONE_DAY_MS);
 | 
			
		||||
        // Sample Balancer on-chain (i.e. via the ERC20BridgeSampler contract) if:
 | 
			
		||||
        // - Cached values are not stale
 | 
			
		||||
        // - There is at least one Balancer pool for this pair
 | 
			
		||||
        const onChain = cachedBalancerPools !== undefined && cachedBalancerPools.length > 0;
 | 
			
		||||
        // Sample Balancer off-chain (i.e. via GraphQL query + `computeBalancerBuy/SellQuote`)
 | 
			
		||||
        // if cached values are stale
 | 
			
		||||
        const offChain = cachedBalancerPools === undefined;
 | 
			
		||||
        return { onChain, offChain };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _getPoolsForPairAsync(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        cacheExpiryMs: number = FIVE_SECONDS_MS,
 | 
			
		||||
    ): Promise<Pool[]> {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        const minTimestamp = Date.now() - cacheExpiryMs;
 | 
			
		||||
        if (value === undefined || value.timestamp < minTimestamp) {
 | 
			
		||||
            const pools = await this._fetchPoolsForPairAsync(takerToken, makerToken);
 | 
			
		||||
            this._cachePoolsForPair(takerToken, makerToken, pools);
 | 
			
		||||
        }
 | 
			
		||||
        return this._cache[key].pools;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected _cachePoolsForPair(takerToken: string, makerToken: string, pools: Pool[]): void {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        this._cache[key] = {
 | 
			
		||||
            pools,
 | 
			
		||||
            timestamp: Date.now(),
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
        try {
 | 
			
		||||
            const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
 | 
			
		||||
            // Sort by maker token balance (descending)
 | 
			
		||||
            const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
 | 
			
		||||
                b.balanceOut.minus(a.balanceOut).toNumber(),
 | 
			
		||||
            );
 | 
			
		||||
            return pools.length > this.maxPoolsFetched ? pools.slice(0, this.maxPoolsFetched) : pools;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _loadTopPoolsAsync(): Promise<void> {
 | 
			
		||||
        const fromToPools: {
 | 
			
		||||
            [from: string]: { [to: string]: Pool[] };
 | 
			
		||||
        } = {};
 | 
			
		||||
 | 
			
		||||
        const pools = await this._fetchTopPoolsAsync();
 | 
			
		||||
        pools.forEach(pool => {
 | 
			
		||||
            const { tokensList } = pool;
 | 
			
		||||
            for (const from of tokensList) {
 | 
			
		||||
                for (const to of tokensList.filter(t => t.toLowerCase() !== from.toLowerCase())) {
 | 
			
		||||
                    if (!fromToPools[from]) {
 | 
			
		||||
                        fromToPools[from] = {};
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!fromToPools[from][to]) {
 | 
			
		||||
                        fromToPools[from][to] = [];
 | 
			
		||||
                    }
 | 
			
		||||
                    try {
 | 
			
		||||
                        // The list of pools must be relevant to `from` and `to`  for `parsePoolData`
 | 
			
		||||
                        const poolData = parsePoolData([pool], from, to);
 | 
			
		||||
                        fromToPools[from][to].push(poolData[0]);
 | 
			
		||||
                        // Cache this as we progress through
 | 
			
		||||
                        this._cachePoolsForPair(from, to, fromToPools[from][to]);
 | 
			
		||||
                    } catch {
 | 
			
		||||
                        // soldier on
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _fetchTopPoolsAsync(): Promise<BalancerPoolResponse[]> {
 | 
			
		||||
        const query = `
 | 
			
		||||
      query {
 | 
			
		||||
          pools (first: ${
 | 
			
		||||
              this.topPoolsFetched
 | 
			
		||||
          }, where: {publicSwap: true, liquidity_gt: 0}, orderBy: swapsCount, orderDirection: desc) {
 | 
			
		||||
            id
 | 
			
		||||
            publicSwap
 | 
			
		||||
            swapFee
 | 
			
		||||
            totalWeight
 | 
			
		||||
            tokensList
 | 
			
		||||
            tokens {
 | 
			
		||||
              id
 | 
			
		||||
              address
 | 
			
		||||
              balance
 | 
			
		||||
              decimals
 | 
			
		||||
              symbol
 | 
			
		||||
              denormWeight
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
    `;
 | 
			
		||||
        try {
 | 
			
		||||
            const response = await fetch(this.subgraphUrl, {
 | 
			
		||||
                method: 'POST',
 | 
			
		||||
                headers: {
 | 
			
		||||
                    Accept: 'application/json',
 | 
			
		||||
                    'Content-Type': 'application/json',
 | 
			
		||||
                },
 | 
			
		||||
                body: JSON.stringify({
 | 
			
		||||
                    query,
 | 
			
		||||
                }),
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const { data } = await response.json();
 | 
			
		||||
            return data.pools;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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,7 +20,7 @@ import {
 | 
			
		||||
    NERVE_BSC_INFOS,
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
    PANCAKESWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    PANCAKESWAP_V2_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    PANCAKESWAPV2_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SADDLE_MAINNET_INFOS,
 | 
			
		||||
    SHELL_POOLS_BY_CHAIN_ID,
 | 
			
		||||
    SMOOTHY_BSC_INFOS,
 | 
			
		||||
@@ -24,6 +29,7 @@ import {
 | 
			
		||||
    SUSHISWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SWERVE_MAINNET_INFOS,
 | 
			
		||||
    UNISWAPV2_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    XSIGMA_MAINNET_INFOS,
 | 
			
		||||
} from './constants';
 | 
			
		||||
import { CurveInfo, ERC20BridgeSource } from './types';
 | 
			
		||||
 | 
			
		||||
@@ -32,7 +38,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
 | 
			
		||||
@@ -194,6 +204,19 @@ export function getSaddleInfosForPair(chainId: ChainId, takerToken: string, make
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getXSigmaInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
 | 
			
		||||
    if (chainId !== ChainId.Mainnet) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
    return Object.values(XSIGMA_MAINNET_INFOS).filter(c =>
 | 
			
		||||
        [makerToken, takerToken].every(
 | 
			
		||||
            t =>
 | 
			
		||||
                (c.tokens.includes(t) && c.metaToken === undefined) ||
 | 
			
		||||
                (c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)),
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getShellLikeInfosForPair(
 | 
			
		||||
    chainId: ChainId,
 | 
			
		||||
    takerToken: string,
 | 
			
		||||
@@ -210,6 +233,11 @@ export function getShellLikeInfosForPair(
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface CurveDetailedInfo extends CurveInfo {
 | 
			
		||||
    makerTokenIdx: number;
 | 
			
		||||
    takerTokenIdx: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getCurveLikeInfosForPair(
 | 
			
		||||
    chainId: ChainId,
 | 
			
		||||
    takerToken: string,
 | 
			
		||||
@@ -222,28 +250,46 @@ export function getCurveLikeInfosForPair(
 | 
			
		||||
        | ERC20BridgeSource.Belt
 | 
			
		||||
        | ERC20BridgeSource.Ellipsis
 | 
			
		||||
        | ERC20BridgeSource.Smoothy
 | 
			
		||||
        | ERC20BridgeSource.Saddle,
 | 
			
		||||
): CurveInfo[] {
 | 
			
		||||
        | ERC20BridgeSource.Saddle
 | 
			
		||||
        | ERC20BridgeSource.XSigma,
 | 
			
		||||
): CurveDetailedInfo[] {
 | 
			
		||||
    let pools: CurveInfo[] = [];
 | 
			
		||||
    switch (source) {
 | 
			
		||||
        case ERC20BridgeSource.Curve:
 | 
			
		||||
            return getCurveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getCurveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Swerve:
 | 
			
		||||
            return getSwerveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getSwerveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.SnowSwap:
 | 
			
		||||
            return getSnowSwapInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getSnowSwapInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Nerve:
 | 
			
		||||
            return getNerveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getNerveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Belt:
 | 
			
		||||
            return getBeltInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getBeltInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Ellipsis:
 | 
			
		||||
            return getEllipsisInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getEllipsisInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Smoothy:
 | 
			
		||||
            return getSmoothyInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getSmoothyInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Saddle:
 | 
			
		||||
            return getSaddleInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            pools = getSaddleInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.XSigma:
 | 
			
		||||
            pools = getXSigmaInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(`Unknown Curve like source ${source}`);
 | 
			
		||||
    }
 | 
			
		||||
    return pools.map(pool => ({
 | 
			
		||||
        ...pool,
 | 
			
		||||
        makerTokenIdx: pool.tokens.indexOf(makerToken),
 | 
			
		||||
        takerTokenIdx: pool.tokens.indexOf(takerToken),
 | 
			
		||||
    }));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function uniswapV2LikeRouterAddress(
 | 
			
		||||
@@ -253,9 +299,13 @@ export function uniswapV2LikeRouterAddress(
 | 
			
		||||
        | ERC20BridgeSource.SushiSwap
 | 
			
		||||
        | ERC20BridgeSource.CryptoCom
 | 
			
		||||
        | ERC20BridgeSource.PancakeSwap
 | 
			
		||||
        | ERC20BridgeSource.PancakeSwapV2
 | 
			
		||||
        | ERC20BridgeSource.BakerySwap
 | 
			
		||||
        | ERC20BridgeSource.KyberDmm
 | 
			
		||||
        | ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
        | ERC20BridgeSource.ApeSwap
 | 
			
		||||
        | ERC20BridgeSource.CafeSwap
 | 
			
		||||
        | ERC20BridgeSource.CheeseSwap
 | 
			
		||||
        | ERC20BridgeSource.JulSwap,
 | 
			
		||||
): string {
 | 
			
		||||
    switch (source) {
 | 
			
		||||
        case ERC20BridgeSource.UniswapV2:
 | 
			
		||||
@@ -266,12 +316,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.PancakeSwapV2:
 | 
			
		||||
            return PANCAKESWAP_V2_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}`);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@ import {
 | 
			
		||||
    PsmInfo,
 | 
			
		||||
    TokenAdjacencyGraph,
 | 
			
		||||
    UniswapV2FillData,
 | 
			
		||||
    UniswapV3FillData,
 | 
			
		||||
} from './types';
 | 
			
		||||
 | 
			
		||||
// tslint:disable: custom-no-magic-numbers no-bitwise
 | 
			
		||||
@@ -39,6 +40,7 @@ export const ONE_HOUR_IN_SECONDS = 60 * 60;
 | 
			
		||||
export const ONE_SECOND_MS = 1000;
 | 
			
		||||
export const NULL_BYTES = '0x';
 | 
			
		||||
export const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
 | 
			
		||||
export const SAMPLER_ADDRESS = '0x5555555555555555555555555555555555555555';
 | 
			
		||||
export const COMPARISON_PRICE_DECIMALS = 10;
 | 
			
		||||
 | 
			
		||||
function valueByChainId<T>(rest: Partial<{ [key in ChainId]: T }>, defaultValue: T): { [key in ChainId]: T } {
 | 
			
		||||
@@ -67,6 +69,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.Balancer,
 | 
			
		||||
            ERC20BridgeSource.BalancerV2,
 | 
			
		||||
            ERC20BridgeSource.Bancor,
 | 
			
		||||
            ERC20BridgeSource.MStable,
 | 
			
		||||
            ERC20BridgeSource.Mooniswap,
 | 
			
		||||
@@ -86,6 +89,8 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
            ERC20BridgeSource.Component,
 | 
			
		||||
            ERC20BridgeSource.Saddle,
 | 
			
		||||
            ERC20BridgeSource.XSigma,
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Ropsten]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
@@ -93,6 +98,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Uniswap,
 | 
			
		||||
            ERC20BridgeSource.UniswapV2,
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]),
 | 
			
		||||
        [ChainId.Kovan]: new SourceFilters([ERC20BridgeSource.Native]),
 | 
			
		||||
@@ -107,9 +113,13 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.Nerve,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwap,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.CafeSwap,
 | 
			
		||||
            ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
            ERC20BridgeSource.JulSwap,
 | 
			
		||||
        ]),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -129,6 +139,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.Balancer,
 | 
			
		||||
            ERC20BridgeSource.BalancerV2,
 | 
			
		||||
            // ERC20BridgeSource.Bancor, // FIXME: Bancor Buys not implemented in Sampler
 | 
			
		||||
            ERC20BridgeSource.MStable,
 | 
			
		||||
            ERC20BridgeSource.Mooniswap,
 | 
			
		||||
@@ -148,6 +159,8 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
            ERC20BridgeSource.Component,
 | 
			
		||||
            ERC20BridgeSource.Saddle,
 | 
			
		||||
            ERC20BridgeSource.XSigma,
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Ropsten]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
@@ -155,6 +168,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Uniswap,
 | 
			
		||||
            ERC20BridgeSource.UniswapV2,
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]),
 | 
			
		||||
        [ChainId.Kovan]: new SourceFilters([ERC20BridgeSource.Native]),
 | 
			
		||||
@@ -169,9 +183,13 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.Nerve,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwap,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.CafeSwap,
 | 
			
		||||
            ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
            ERC20BridgeSource.JulSwap,
 | 
			
		||||
        ]),
 | 
			
		||||
    },
 | 
			
		||||
    new SourceFilters([]),
 | 
			
		||||
@@ -285,6 +303,7 @@ export const MAINNET_TOKENS = {
 | 
			
		||||
    STABLEx: '0xcd91538b91b4ba7797d39a2f66e63810b50a33d0',
 | 
			
		||||
    alUSD: '0xbc6da0fe9ad5f3b0d58160288917aa56653660e9',
 | 
			
		||||
    FRAX: '0x853d955acef822db058eb8505911ed77f175b99e',
 | 
			
		||||
    LUSD: '0x5f98805a4e8be255a32880fdec7f6728c6568ba0',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const BSC_TOKENS = {
 | 
			
		||||
@@ -321,11 +340,11 @@ export const CURVE_POOLS = {
 | 
			
		||||
    oBTC: '0xd81da8d904b52208541bade1bd6595d8a251f8dd', // 21.obtc
 | 
			
		||||
    UST: '0x890f4e345b1daed0367a877a1612f86a1f86985f', // 22.ust
 | 
			
		||||
    eurs: '0x0ce6a5ff5217e38315f87032cf90686c96627caa', // 23.eurs
 | 
			
		||||
    // seth: '0xc5424b857f758e906013f3555dad202e4bdb4567', // 24.seth
 | 
			
		||||
    seth: '0xc5424b857f758e906013f3555dad202e4bdb4567', // 24.seth
 | 
			
		||||
    aave: '0xdebf20617708857ebe4f679508e7b7863a8a8eee', // 25.aave
 | 
			
		||||
    // curve steth: '0xdc24316b9ae028f1497c275eb9192a3ea0f67022' // 26.stETH
 | 
			
		||||
    steth: '0xdc24316b9ae028f1497c275eb9192a3ea0f67022', // 26.stETH
 | 
			
		||||
    saave: '0xeb16ae0052ed37f479f7fe63849198df1765a733', // saave
 | 
			
		||||
    // ankreth: '0xa96a65c051bf88b4095ee1f2451c2a9d43f53ae2', // ankreth
 | 
			
		||||
    ankreth: '0xa96a65c051bf88b4095ee1f2451c2a9d43f53ae2', // ankreth
 | 
			
		||||
    USDP: '0x42d7025938bec20b69cbae5a77421082407f053a', // usdp
 | 
			
		||||
    ib: '0x2dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf', // iron bank
 | 
			
		||||
    link: '0xf178c0b5bb7e7abf4e12a4838c7b7c5ba2c623c0', // link
 | 
			
		||||
@@ -334,6 +353,8 @@ export const CURVE_POOLS = {
 | 
			
		||||
    STABLEx: '0x3252efd4ea2d6c78091a1f43982ee2c3659cc3d1',
 | 
			
		||||
    alUSD: '0x43b4fdfd4ff969587185cdb6f0bd875c5fc83f8c',
 | 
			
		||||
    FRAX: '0xd632f22692fac7611d2aa1c0d552930d43caed3b',
 | 
			
		||||
    LUSD: '0xed279fdd11ca84beef15af5d39bb4d4bee23f0ca',
 | 
			
		||||
    BUSD: '0x4807862aa8b2bf68830e4c8dc86d0e9a998e085a',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const SWERVE_POOLS = {
 | 
			
		||||
@@ -343,7 +364,12 @@ export const SWERVE_POOLS = {
 | 
			
		||||
export const SNOWSWAP_POOLS = {
 | 
			
		||||
    yUSD: '0xbf7ccd6c446acfcc5df023043f2167b62e81899b',
 | 
			
		||||
    yVault: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b',
 | 
			
		||||
    eth: '0x16bea2e63adade5984298d53a4d4d9c09e278192',
 | 
			
		||||
    // POOL Disabled as it uses WETH over ETH
 | 
			
		||||
    // There is a conflict with Curve and SnowSwap
 | 
			
		||||
    // where Curve uses ETH and SnowSwap uses WETH
 | 
			
		||||
    // To re-enable this we need to flag an WETH
 | 
			
		||||
    // unwrap or not
 | 
			
		||||
    // eth: '0x16bea2e63adade5984298d53a4d4d9c09e278192',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const SMOOTHY_POOLS = {
 | 
			
		||||
@@ -367,6 +393,10 @@ export const ELLIPSIS_POOLS = {
 | 
			
		||||
    threePool: '0x160caed03795365f3a589f10c379ffa7d75d4e76',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const XSIGMA_POOLS = {
 | 
			
		||||
    stable: '0x3333333ACdEdBbC9Ad7bda0876e60714195681c5',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: [
 | 
			
		||||
@@ -478,147 +508,175 @@ 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,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.LUSD]: createCurveMetaTriPool({
 | 
			
		||||
        token: MAINNET_TOKENS.LUSD,
 | 
			
		||||
        pool: CURVE_POOLS.LUSD,
 | 
			
		||||
        gasSchedule: 387e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.BUSD]: createCurveMetaTriPool({
 | 
			
		||||
        token: MAINNET_TOKENS.BUSD,
 | 
			
		||||
        pool: CURVE_POOLS.BUSD,
 | 
			
		||||
        gasSchedule: 387e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.steth]: createCurveExchangePool({
 | 
			
		||||
        // This pool uses ETH
 | 
			
		||||
        tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.stETH],
 | 
			
		||||
        pool: CURVE_POOLS.steth,
 | 
			
		||||
        gasSchedule: 151e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.seth]: createCurveExchangePool({
 | 
			
		||||
        // This pool uses ETH
 | 
			
		||||
        tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.sETH],
 | 
			
		||||
        pool: CURVE_POOLS.seth,
 | 
			
		||||
        gasSchedule: 187e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.ankreth]: createCurveExchangePool({
 | 
			
		||||
        // This pool uses ETH
 | 
			
		||||
        tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.ankrETH],
 | 
			
		||||
        pool: CURVE_POOLS.ankreth,
 | 
			
		||||
        gasSchedule: 125e3,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -626,7 +684,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,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -634,30 +692,31 @@ 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,
 | 
			
		||||
    }),
 | 
			
		||||
    [SNOWSWAP_POOLS.eth]: createCurveExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.vETH, MAINNET_TOKENS.ankrETH, MAINNET_TOKENS.crETH],
 | 
			
		||||
        pool: SNOWSWAP_POOLS.eth,
 | 
			
		||||
        gasSchedule: 1000e3,
 | 
			
		||||
        gasSchedule: 1490e3,
 | 
			
		||||
    }),
 | 
			
		||||
    // Unsupported due to collision with WETH and ETH with execution using MixinCurve
 | 
			
		||||
    // [SNOWSWAP_POOLS.eth]: createCurveExchangePool({
 | 
			
		||||
    //     tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.vETH, MAINNET_TOKENS.ankrETH, MAINNET_TOKENS.crETH],
 | 
			
		||||
    //     pool: SNOWSWAP_POOLS.eth,
 | 
			
		||||
    //     gasSchedule: 990e3,
 | 
			
		||||
    // }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -665,6 +724,14 @@ 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: 140e3,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const XSIGMA_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    [XSIGMA_POOLS.stable]: createCurveExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT],
 | 
			
		||||
        pool: XSIGMA_POOLS.stable,
 | 
			
		||||
        gasSchedule: 150e3,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
@@ -678,18 +745,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 } = {
 | 
			
		||||
@@ -709,7 +775,7 @@ export const SMOOTHY_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
            MAINNET_TOKENS.GUSD,
 | 
			
		||||
        ],
 | 
			
		||||
        metaToken: undefined,
 | 
			
		||||
        gasSchedule: 200e3,
 | 
			
		||||
        gasSchedule: 190e3,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -721,7 +787,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,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -733,7 +799,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,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -744,6 +810,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>(
 | 
			
		||||
    {
 | 
			
		||||
@@ -978,9 +1045,31 @@ export const COMPONENT_POOLS_BY_CHAIN_ID = valueByChainId(
 | 
			
		||||
    },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const BALANCER_V2_VAULT_ADDRESS_BY_CHAIN = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: '0xba12222222228d8ba445958a75a0704d566bf2c8',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const BALANCER_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer';
 | 
			
		||||
export const BALANCER_TOP_POOLS_FETCHED = 250;
 | 
			
		||||
export const BALANCER_MAX_POOLS_FETCHED = 3;
 | 
			
		||||
export const BALANCER_V2_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2';
 | 
			
		||||
 | 
			
		||||
export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: {
 | 
			
		||||
            quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6',
 | 
			
		||||
            router: '0xe592427a0aece92de3edee1f18e0157c05861564',
 | 
			
		||||
        },
 | 
			
		||||
        [ChainId.Ropsten]: {
 | 
			
		||||
            quoter: '0x2f9e608fd881861b8916257b76613cb22ee0652c',
 | 
			
		||||
            router: '0x03782388516e94fcd4c18666303601a12aa729ea',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    { quoter: NULL_ADDRESS, router: NULL_ADDRESS },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// BSC
 | 
			
		||||
@@ -992,7 +1081,7 @@ export const PANCAKESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const PANCAKESWAP_V2_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
export const PANCAKESWAPV2_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.BSC]: '0x10ed43c718714eb63d5aa57b78b54704e256024e',
 | 
			
		||||
    },
 | 
			
		||||
@@ -1006,6 +1095,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
 | 
			
		||||
@@ -1037,6 +1154,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
    [ERC20BridgeSource.Ellipsis]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Smoothy]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Saddle]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.XSigma]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.MultiBridge]: () => 350e3,
 | 
			
		||||
    [ERC20BridgeSource.UniswapV2]: (fillData?: FillData) => {
 | 
			
		||||
        // TODO: Different base cost if to/from ETH.
 | 
			
		||||
@@ -1075,17 +1193,12 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
        return gas;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.Balancer]: () => 120e3,
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: () => 100e3,
 | 
			
		||||
    [ERC20BridgeSource.Cream]: () => 120e3,
 | 
			
		||||
    [ERC20BridgeSource.MStable]: () => 700e3,
 | 
			
		||||
    [ERC20BridgeSource.MakerPsm]: (fillData?: FillData) => {
 | 
			
		||||
        const psmFillData = fillData as MakerPsmFillData;
 | 
			
		||||
 | 
			
		||||
        // TODO(kimpers): update with more accurate numbers after allowances have been set
 | 
			
		||||
        if (psmFillData.takerToken === psmFillData.gemTokenAddress) {
 | 
			
		||||
            return psmFillData.isSellOperation ? 389e3 : 423e3;
 | 
			
		||||
        } else {
 | 
			
		||||
            return 444e3;
 | 
			
		||||
        }
 | 
			
		||||
        return psmFillData.takerToken === psmFillData.gemTokenAddress ? 210e3 : 290e3;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.Mooniswap]: () => 130e3,
 | 
			
		||||
    [ERC20BridgeSource.Shell]: () => 170e3,
 | 
			
		||||
@@ -1136,6 +1249,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;
 | 
			
		||||
@@ -1145,7 +1267,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
        }
 | 
			
		||||
        return gas;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.PancakeSwapV2]: (fillData?: FillData) => {
 | 
			
		||||
    [ERC20BridgeSource.ApeSwap]: (fillData?: FillData) => {
 | 
			
		||||
        // TODO: Different base cost if to/from ETH.
 | 
			
		||||
        let gas = 90e3;
 | 
			
		||||
        const path = (fillData as UniswapV2FillData).tokenAddressPath;
 | 
			
		||||
@@ -1154,6 +1276,41 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
        }
 | 
			
		||||
        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;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.UniswapV3]: (fillData?: FillData) => {
 | 
			
		||||
        let gas = 160e3;
 | 
			
		||||
        const path = (fillData as UniswapV3FillData).tokenAddressPath;
 | 
			
		||||
        if (path.length > 2) {
 | 
			
		||||
            gas += (path.length - 2) * 117e3; // +117k for each hop.
 | 
			
		||||
        }
 | 
			
		||||
        return gas;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE };
 | 
			
		||||
@@ -1177,5 +1334,6 @@ export const DEFAULT_GET_MARKET_ORDERS_OPTS: GetMarketOrdersOpts = {
 | 
			
		||||
    exchangeProxyOverhead: () => ZERO_AMOUNT,
 | 
			
		||||
    allowFallback: true,
 | 
			
		||||
    shouldGenerateQuoteReport: true,
 | 
			
		||||
    shouldIncludePriceComparisonsReport: false,
 | 
			
		||||
    tokenAdjacencyGraph: { default: [] },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,109 +0,0 @@
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from 'cream-sor';
 | 
			
		||||
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED } from './constants';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:boolean-naming
 | 
			
		||||
 | 
			
		||||
interface CacheValue {
 | 
			
		||||
    timestamp: number;
 | 
			
		||||
    pools: Pool[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tslint:disable:custom-no-magic-numbers
 | 
			
		||||
const FIVE_SECONDS_MS = 5 * 1000;
 | 
			
		||||
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
 | 
			
		||||
const DEFAULT_TIMEOUT_MS = 1000;
 | 
			
		||||
// tslint:enable:custom-no-magic-numbers
 | 
			
		||||
 | 
			
		||||
export class CreamPoolsCache {
 | 
			
		||||
    constructor(
 | 
			
		||||
        private readonly _cache: { [key: string]: CacheValue } = {},
 | 
			
		||||
        private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    public async getPoolsForPairAsync(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        timeoutMs: number = DEFAULT_TIMEOUT_MS,
 | 
			
		||||
    ): Promise<Pool[]> {
 | 
			
		||||
        const timeout = new Promise<Pool[]>(resolve => setTimeout(resolve, timeoutMs, []));
 | 
			
		||||
        return Promise.race([this._getPoolsForPairAsync(takerToken, makerToken), timeout]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getCachedPoolAddressesForPair(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        cacheExpiryMs?: number,
 | 
			
		||||
    ): string[] | undefined {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        if (cacheExpiryMs === undefined) {
 | 
			
		||||
            return value === undefined ? [] : value.pools.map(pool => pool.id);
 | 
			
		||||
        }
 | 
			
		||||
        const minTimestamp = Date.now() - cacheExpiryMs;
 | 
			
		||||
        if (value === undefined || value.timestamp < minTimestamp) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        } else {
 | 
			
		||||
            return value.pools.map(pool => pool.id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public howToSampleCream(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        isAllowedSource: boolean,
 | 
			
		||||
    ): { onChain: boolean; offChain: boolean } {
 | 
			
		||||
        // If CREAM is excluded as a source, do not sample.
 | 
			
		||||
        if (!isAllowedSource) {
 | 
			
		||||
            return { onChain: false, offChain: false };
 | 
			
		||||
        }
 | 
			
		||||
        const cachedCreamPools = this.getCachedPoolAddressesForPair(takerToken, makerToken, ONE_DAY_MS);
 | 
			
		||||
        // Sample CREAM on-chain (i.e. via the ERC20BridgeSampler contract) if:
 | 
			
		||||
        // - Cached values are not stale
 | 
			
		||||
        // - There is at least one CREAM pool for this pair
 | 
			
		||||
        const onChain = cachedCreamPools !== undefined && cachedCreamPools.length > 0;
 | 
			
		||||
        // Sample CREAM off-chain (i.e. via GraphQL query + `computeCreamBuy/SellQuote`)
 | 
			
		||||
        // if cached values are stale
 | 
			
		||||
        const offChain = cachedCreamPools === undefined;
 | 
			
		||||
        return { onChain, offChain };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _getPoolsForPairAsync(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        cacheExpiryMs: number = FIVE_SECONDS_MS,
 | 
			
		||||
    ): Promise<Pool[]> {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        const minTimestamp = Date.now() - cacheExpiryMs;
 | 
			
		||||
        if (value === undefined || value.timestamp < minTimestamp) {
 | 
			
		||||
            const pools = await this._fetchPoolsForPairAsync(takerToken, makerToken);
 | 
			
		||||
            const timestamp = Date.now();
 | 
			
		||||
            this._cache[key] = {
 | 
			
		||||
                pools,
 | 
			
		||||
                timestamp,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        return this._cache[key].pools;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // tslint:disable-next-line: prefer-function-over-method
 | 
			
		||||
    protected async _loadTopPoolsAsync(): Promise<void> {
 | 
			
		||||
        // Do nothing
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // tslint:disable-next-line:prefer-function-over-method
 | 
			
		||||
    protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
        try {
 | 
			
		||||
            const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
 | 
			
		||||
            // Sort by maker token balance (descending)
 | 
			
		||||
            const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
 | 
			
		||||
                b.balanceOut.minus(a.balanceOut).toNumber(),
 | 
			
		||||
            );
 | 
			
		||||
            return pools.length > this.maxPoolsFetched ? pools.slice(0, this.maxPoolsFetched) : pools;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -16,7 +16,14 @@ import {
 | 
			
		||||
    getNativeAdjustedMakerFillAmount,
 | 
			
		||||
} from '../utils';
 | 
			
		||||
 | 
			
		||||
import { generateQuoteReport, QuoteReport } from './../quote_report_generator';
 | 
			
		||||
import {
 | 
			
		||||
    dexSampleToReportSource,
 | 
			
		||||
    generateQuoteReport,
 | 
			
		||||
    multiHopSampleToReportSource,
 | 
			
		||||
    nativeOrderToReportEntry,
 | 
			
		||||
    PriceComparisonsReport,
 | 
			
		||||
    QuoteReport,
 | 
			
		||||
} from './../quote_report_generator';
 | 
			
		||||
import { getComparisonPrices } from './comparison_price';
 | 
			
		||||
import {
 | 
			
		||||
    BUY_SOURCE_FILTER_BY_CHAIN_ID,
 | 
			
		||||
@@ -68,6 +75,27 @@ export class MarketOperationUtils {
 | 
			
		||||
        return generateQuoteReport(side, quotes.nativeOrders, liquidityDelivered, comparisonPrice, quoteRequestor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static _computePriceComparisonsReport(
 | 
			
		||||
        quoteRequestor: QuoteRequestor | undefined,
 | 
			
		||||
        marketSideLiquidity: MarketSideLiquidity,
 | 
			
		||||
        comparisonPrice?: BigNumber | undefined,
 | 
			
		||||
    ): PriceComparisonsReport {
 | 
			
		||||
        const { side, quotes } = marketSideLiquidity;
 | 
			
		||||
        const dexSources = _.flatten(quotes.dexQuotes).map(quote => dexSampleToReportSource(quote, side));
 | 
			
		||||
        const multiHopSources = quotes.twoHopQuotes.map(quote => multiHopSampleToReportSource(quote, side));
 | 
			
		||||
        const nativeSources = quotes.nativeOrders.map(order =>
 | 
			
		||||
            nativeOrderToReportEntry(
 | 
			
		||||
                order.type,
 | 
			
		||||
                order as any,
 | 
			
		||||
                order.fillableTakerAmount,
 | 
			
		||||
                comparisonPrice,
 | 
			
		||||
                quoteRequestor,
 | 
			
		||||
            ),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return { dexSources, multiHopSources, nativeSources };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private readonly _sampler: DexOrderSampler,
 | 
			
		||||
        private readonly contractAddresses: AssetSwapperContractAddresses,
 | 
			
		||||
@@ -100,29 +128,6 @@ export class MarketOperationUtils {
 | 
			
		||||
        const quoteSourceFilters = this._sellSources.merge(requestFilters);
 | 
			
		||||
        const feeSourceFilters = this._feeSources.exclude(_opts.excludedFeeSources);
 | 
			
		||||
 | 
			
		||||
        const {
 | 
			
		||||
            onChain: sampleBalancerOnChain,
 | 
			
		||||
            offChain: sampleBalancerOffChain,
 | 
			
		||||
        } = this._sampler.balancerPoolsCache.howToSampleBalancer(
 | 
			
		||||
            takerToken,
 | 
			
		||||
            makerToken,
 | 
			
		||||
            quoteSourceFilters.isAllowed(ERC20BridgeSource.Balancer),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const {
 | 
			
		||||
            onChain: sampleCreamOnChain,
 | 
			
		||||
            offChain: sampleCreamOffChain,
 | 
			
		||||
        } = this._sampler.creamPoolsCache.howToSampleCream(
 | 
			
		||||
            takerToken,
 | 
			
		||||
            makerToken,
 | 
			
		||||
            quoteSourceFilters.isAllowed(ERC20BridgeSource.Cream),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const offChainSources = [
 | 
			
		||||
            ...(!sampleCreamOnChain ? [ERC20BridgeSource.Cream] : []),
 | 
			
		||||
            ...(!sampleBalancerOnChain ? [ERC20BridgeSource.Balancer] : []),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        // Used to determine whether the tx origin is an EOA or a contract
 | 
			
		||||
        const txOrigin = (_opts.rfqt && _opts.rfqt.txOrigin) || NULL_ADDRESS;
 | 
			
		||||
 | 
			
		||||
@@ -146,12 +151,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                this._nativeFeeTokenAmount,
 | 
			
		||||
            ),
 | 
			
		||||
            // Get sell quotes for taker -> maker.
 | 
			
		||||
            this._sampler.getSellQuotes(
 | 
			
		||||
                quoteSourceFilters.exclude(offChainSources).sources,
 | 
			
		||||
                makerToken,
 | 
			
		||||
                takerToken,
 | 
			
		||||
                sampleAmounts,
 | 
			
		||||
            ),
 | 
			
		||||
            this._sampler.getSellQuotes(quoteSourceFilters.sources, makerToken, takerToken, sampleAmounts),
 | 
			
		||||
            this._sampler.getTwoHopSellQuotes(
 | 
			
		||||
                quoteSourceFilters.isAllowed(ERC20BridgeSource.MultiHop) ? quoteSourceFilters.sources : [],
 | 
			
		||||
                makerToken,
 | 
			
		||||
@@ -161,13 +161,8 @@ export class MarketOperationUtils {
 | 
			
		||||
            this._sampler.isAddressContract(txOrigin),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const offChainBalancerPromise = sampleBalancerOffChain
 | 
			
		||||
            ? this._sampler.getBalancerSellQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
 | 
			
		||||
            : Promise.resolve([]);
 | 
			
		||||
 | 
			
		||||
        const offChainCreamPromise = sampleCreamOffChain
 | 
			
		||||
            ? this._sampler.getCreamSellQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
 | 
			
		||||
            : Promise.resolve([]);
 | 
			
		||||
        // Refresh the cached pools asynchronously if required
 | 
			
		||||
        void this._refreshPoolCacheIfRequiredAsync(takerToken, makerToken);
 | 
			
		||||
 | 
			
		||||
        const [
 | 
			
		||||
            [
 | 
			
		||||
@@ -179,9 +174,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                rawTwoHopQuotes,
 | 
			
		||||
                isTxOriginContract,
 | 
			
		||||
            ],
 | 
			
		||||
            offChainBalancerQuotes,
 | 
			
		||||
            offChainCreamQuotes,
 | 
			
		||||
        ] = await Promise.all([samplerPromise, offChainBalancerPromise, offChainCreamPromise]);
 | 
			
		||||
        ] = await Promise.all([samplerPromise]);
 | 
			
		||||
 | 
			
		||||
        // Filter out any invalid two hop quotes where we couldn't find a route
 | 
			
		||||
        const twoHopQuotes = rawTwoHopQuotes.filter(
 | 
			
		||||
@@ -210,7 +203,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                nativeOrders: limitOrdersWithFillableAmounts,
 | 
			
		||||
                rfqtIndicativeQuotes: [],
 | 
			
		||||
                twoHopQuotes,
 | 
			
		||||
                dexQuotes: dexQuotes.concat([...offChainBalancerQuotes, ...offChainCreamQuotes]),
 | 
			
		||||
                dexQuotes,
 | 
			
		||||
            },
 | 
			
		||||
            isRfqSupported,
 | 
			
		||||
        };
 | 
			
		||||
@@ -236,29 +229,6 @@ export class MarketOperationUtils {
 | 
			
		||||
        const quoteSourceFilters = this._buySources.merge(requestFilters);
 | 
			
		||||
        const feeSourceFilters = this._feeSources.exclude(_opts.excludedFeeSources);
 | 
			
		||||
 | 
			
		||||
        const {
 | 
			
		||||
            onChain: sampleBalancerOnChain,
 | 
			
		||||
            offChain: sampleBalancerOffChain,
 | 
			
		||||
        } = this._sampler.balancerPoolsCache.howToSampleBalancer(
 | 
			
		||||
            takerToken,
 | 
			
		||||
            makerToken,
 | 
			
		||||
            quoteSourceFilters.isAllowed(ERC20BridgeSource.Balancer),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const {
 | 
			
		||||
            onChain: sampleCreamOnChain,
 | 
			
		||||
            offChain: sampleCreamOffChain,
 | 
			
		||||
        } = this._sampler.creamPoolsCache.howToSampleCream(
 | 
			
		||||
            takerToken,
 | 
			
		||||
            makerToken,
 | 
			
		||||
            quoteSourceFilters.isAllowed(ERC20BridgeSource.Cream),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const offChainSources = [
 | 
			
		||||
            ...(!sampleCreamOnChain ? [ERC20BridgeSource.Cream] : []),
 | 
			
		||||
            ...(!sampleBalancerOnChain ? [ERC20BridgeSource.Balancer] : []),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        // Used to determine whether the tx origin is an EOA or a contract
 | 
			
		||||
        const txOrigin = (_opts.rfqt && _opts.rfqt.txOrigin) || NULL_ADDRESS;
 | 
			
		||||
 | 
			
		||||
@@ -282,12 +252,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                this._nativeFeeTokenAmount,
 | 
			
		||||
            ),
 | 
			
		||||
            // Get buy quotes for taker -> maker.
 | 
			
		||||
            this._sampler.getBuyQuotes(
 | 
			
		||||
                quoteSourceFilters.exclude(offChainSources).sources,
 | 
			
		||||
                makerToken,
 | 
			
		||||
                takerToken,
 | 
			
		||||
                sampleAmounts,
 | 
			
		||||
            ),
 | 
			
		||||
            this._sampler.getBuyQuotes(quoteSourceFilters.sources, makerToken, takerToken, sampleAmounts),
 | 
			
		||||
            this._sampler.getTwoHopBuyQuotes(
 | 
			
		||||
                quoteSourceFilters.isAllowed(ERC20BridgeSource.MultiHop) ? quoteSourceFilters.sources : [],
 | 
			
		||||
                makerToken,
 | 
			
		||||
@@ -297,13 +262,8 @@ export class MarketOperationUtils {
 | 
			
		||||
            this._sampler.isAddressContract(txOrigin),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        const offChainBalancerPromise = sampleBalancerOffChain
 | 
			
		||||
            ? this._sampler.getBalancerBuyQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
 | 
			
		||||
            : Promise.resolve([]);
 | 
			
		||||
 | 
			
		||||
        const offChainCreamPromise = sampleCreamOffChain
 | 
			
		||||
            ? this._sampler.getCreamBuyQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
 | 
			
		||||
            : Promise.resolve([]);
 | 
			
		||||
        // Refresh the cached pools asynchronously if required
 | 
			
		||||
        void this._refreshPoolCacheIfRequiredAsync(takerToken, makerToken);
 | 
			
		||||
 | 
			
		||||
        const [
 | 
			
		||||
            [
 | 
			
		||||
@@ -315,9 +275,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                rawTwoHopQuotes,
 | 
			
		||||
                isTxOriginContract,
 | 
			
		||||
            ],
 | 
			
		||||
            offChainBalancerQuotes,
 | 
			
		||||
            offChainCreamQuotes,
 | 
			
		||||
        ] = await Promise.all([samplerPromise, offChainBalancerPromise, offChainCreamPromise]);
 | 
			
		||||
        ] = await Promise.all([samplerPromise]);
 | 
			
		||||
 | 
			
		||||
        // Filter out any invalid two hop quotes where we couldn't find a route
 | 
			
		||||
        const twoHopQuotes = rawTwoHopQuotes.filter(
 | 
			
		||||
@@ -346,7 +304,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                nativeOrders: limitOrdersWithFillableAmounts,
 | 
			
		||||
                rfqtIndicativeQuotes: [],
 | 
			
		||||
                twoHopQuotes,
 | 
			
		||||
                dexQuotes: dexQuotes.concat(offChainBalancerQuotes, offChainCreamQuotes),
 | 
			
		||||
                dexQuotes,
 | 
			
		||||
            },
 | 
			
		||||
            isRfqSupported,
 | 
			
		||||
        };
 | 
			
		||||
@@ -554,20 +512,29 @@ export class MarketOperationUtils {
 | 
			
		||||
            throw new Error(AggregationError.NoOptimalPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Generate a fallback path if native orders are in the optimal path.
 | 
			
		||||
        const nativeFills = optimalPath.fills.filter(f => f.source === ERC20BridgeSource.Native);
 | 
			
		||||
        if (opts.allowFallback && nativeFills.length !== 0) {
 | 
			
		||||
        // Generate a fallback path if sources requiring a fallback (fragile) are in the optimal path.
 | 
			
		||||
        // Native is relatively fragile (limit order collision, expiry, or lack of available maker balance)
 | 
			
		||||
        // LiquidityProvider is relatively fragile (collision)
 | 
			
		||||
        const fragileSources = [ERC20BridgeSource.Native, ERC20BridgeSource.LiquidityProvider];
 | 
			
		||||
        const fragileFills = optimalPath.fills.filter(f => fragileSources.includes(f.source));
 | 
			
		||||
        if (opts.allowFallback && fragileFills.length !== 0) {
 | 
			
		||||
            // We create a fallback path that is exclusive of Native liquidity
 | 
			
		||||
            // This is the optimal on-chain path for the entire input amount
 | 
			
		||||
            const nonNativeFills = fills.filter(p => p.length > 0 && p[0].source !== ERC20BridgeSource.Native);
 | 
			
		||||
            const nonNativeOptimalPath = await findOptimalPathAsync(side, nonNativeFills, inputAmount, opts.runLimit);
 | 
			
		||||
            const sturdyFills = fills.filter(p => p.length > 0 && !fragileSources.includes(p[0].source));
 | 
			
		||||
            const sturdyOptimalPath = await findOptimalPathAsync(side, sturdyFills, inputAmount, opts.runLimit, {
 | 
			
		||||
                ...penaltyOpts,
 | 
			
		||||
                exchangeProxyOverhead: (sourceFlags: number) =>
 | 
			
		||||
                    // tslint:disable-next-line: no-bitwise
 | 
			
		||||
                    penaltyOpts.exchangeProxyOverhead(sourceFlags | optimalPath.sourceFlags),
 | 
			
		||||
            });
 | 
			
		||||
            // Calculate the slippage of on-chain sources compared to the most optimal path
 | 
			
		||||
            // if within an acceptable threshold we enable a fallback to prevent reverts
 | 
			
		||||
            if (
 | 
			
		||||
                nonNativeOptimalPath !== undefined &&
 | 
			
		||||
                (nativeFills.length === optimalPath.fills.length ||
 | 
			
		||||
                    nonNativeOptimalPath.adjustedSlippage(optimalPathRate) <= maxFallbackSlippage)
 | 
			
		||||
                sturdyOptimalPath !== undefined &&
 | 
			
		||||
                (fragileFills.length === optimalPath.fills.length ||
 | 
			
		||||
                    sturdyOptimalPath.adjustedSlippage(optimalPathRate) <= maxFallbackSlippage)
 | 
			
		||||
            ) {
 | 
			
		||||
                optimalPath.addFallback(nonNativeOptimalPath);
 | 
			
		||||
                optimalPath.addFallback(sturdyOptimalPath);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        const collapsedPath = optimalPath.collapse(orderOpts);
 | 
			
		||||
@@ -738,7 +705,27 @@ export class MarketOperationUtils {
 | 
			
		||||
                wholeOrderPrice,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        return { ...optimizerResult, quoteReport };
 | 
			
		||||
 | 
			
		||||
        let priceComparisonsReport: PriceComparisonsReport | undefined;
 | 
			
		||||
        if (_opts.shouldIncludePriceComparisonsReport) {
 | 
			
		||||
            priceComparisonsReport = MarketOperationUtils._computePriceComparisonsReport(
 | 
			
		||||
                _opts.rfqt ? _opts.rfqt.quoteRequestor : undefined,
 | 
			
		||||
                marketSideLiquidity,
 | 
			
		||||
                wholeOrderPrice,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        return { ...optimizerResult, quoteReport, priceComparisonsReport };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async _refreshPoolCacheIfRequiredAsync(takerToken: string, makerToken: string): Promise<void> {
 | 
			
		||||
        void Promise.all(
 | 
			
		||||
            Object.values(this._sampler.poolsCaches).map(async cache => {
 | 
			
		||||
                if (cache.isFresh(takerToken, makerToken)) {
 | 
			
		||||
                    return Promise.resolve([]);
 | 
			
		||||
                }
 | 
			
		||||
                return cache.getFreshPoolsForPairAsync(takerToken, makerToken);
 | 
			
		||||
            }),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,14 @@ import { MAX_UINT256, ZERO_AMOUNT } from './constants';
 | 
			
		||||
import {
 | 
			
		||||
    AggregationError,
 | 
			
		||||
    BalancerFillData,
 | 
			
		||||
    BalancerV2FillData,
 | 
			
		||||
    BancorFillData,
 | 
			
		||||
    CollapsedFill,
 | 
			
		||||
    CurveFillData,
 | 
			
		||||
    DexSample,
 | 
			
		||||
    DODOFillData,
 | 
			
		||||
    ERC20BridgeSource,
 | 
			
		||||
    FillData,
 | 
			
		||||
    GenericRouterFillData,
 | 
			
		||||
    KyberFillData,
 | 
			
		||||
    LiquidityProviderFillData,
 | 
			
		||||
@@ -28,6 +30,7 @@ import {
 | 
			
		||||
    OrderDomain,
 | 
			
		||||
    ShellFillData,
 | 
			
		||||
    UniswapV2FillData,
 | 
			
		||||
    UniswapV3FillData,
 | 
			
		||||
} from './types';
 | 
			
		||||
 | 
			
		||||
// tslint:disable completed-docs
 | 
			
		||||
@@ -41,6 +44,11 @@ export interface CreateOrderFromPathOpts {
 | 
			
		||||
    bridgeSlippage: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface FinalUniswapV3FillData extends Omit<UniswapV3FillData, 'uniswapPaths'> {
 | 
			
		||||
    // The uniswap-encoded path that can fll the maximum input amount.
 | 
			
		||||
    uniswapPath: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function createOrdersFromTwoHopSample(
 | 
			
		||||
    sample: DexSample<MultiHopFillData>,
 | 
			
		||||
    opts: CreateOrderFromPathOpts,
 | 
			
		||||
@@ -75,6 +83,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
    switch (source) {
 | 
			
		||||
        case ERC20BridgeSource.Balancer:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Balancer, 'Balancer');
 | 
			
		||||
        case ERC20BridgeSource.BalancerV2:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.BalancerV2, 'BalancerV2');
 | 
			
		||||
        case ERC20BridgeSource.Bancor:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Bancor, 'Bancor');
 | 
			
		||||
        // case ERC20BridgeSource.CoFiX:
 | 
			
		||||
@@ -120,6 +130,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,8 +146,18 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Curve, 'Smoothy');
 | 
			
		||||
        case ERC20BridgeSource.Saddle:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Saddle');
 | 
			
		||||
        case ERC20BridgeSource.PancakeSwapV2:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'PancakeSwapV2');
 | 
			
		||||
        case ERC20BridgeSource.XSigma:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Curve, 'xSigma');
 | 
			
		||||
        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');
 | 
			
		||||
        case ERC20BridgeSource.UniswapV3:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV3, 'UniswapV3');
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(AggregationError.NoBridgeForSource);
 | 
			
		||||
    }
 | 
			
		||||
@@ -165,6 +187,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
        case ERC20BridgeSource.Ellipsis:
 | 
			
		||||
        case ERC20BridgeSource.Smoothy:
 | 
			
		||||
        case ERC20BridgeSource.Saddle:
 | 
			
		||||
        case ERC20BridgeSource.XSigma:
 | 
			
		||||
            const curveFillData = (order as OptimizedMarketBridgeOrder<CurveFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([
 | 
			
		||||
                curveFillData.pool.poolAddress,
 | 
			
		||||
@@ -178,6 +201,11 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
            const balancerFillData = (order as OptimizedMarketBridgeOrder<BalancerFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([balancerFillData.poolAddress]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.BalancerV2:
 | 
			
		||||
            const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
 | 
			
		||||
            const { vault, poolId } = balancerV2FillData;
 | 
			
		||||
            bridgeData = encoder.encode([vault, poolId]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Bancor:
 | 
			
		||||
            const bancorFillData = (order as OptimizedMarketBridgeOrder<BancorFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([bancorFillData.networkAddress, bancorFillData.path]);
 | 
			
		||||
@@ -187,9 +215,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.PancakeSwapV2:
 | 
			
		||||
        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;
 | 
			
		||||
@@ -238,6 +270,10 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
            const psmFillData = (order as OptimizedMarketBridgeOrder<MakerPsmFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([psmFillData.psmAddress, psmFillData.gemTokenAddress]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.UniswapV3:
 | 
			
		||||
            const uniswapV3FillData = (order as OptimizedMarketBridgeOrder<FinalUniswapV3FillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([uniswapV3FillData.router, uniswapV3FillData.uniswapPath]);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(AggregationError.NoBridgeForSource);
 | 
			
		||||
    }
 | 
			
		||||
@@ -256,7 +292,7 @@ export function createBridgeOrder(
 | 
			
		||||
        takerToken,
 | 
			
		||||
        makerAmount,
 | 
			
		||||
        takerAmount,
 | 
			
		||||
        fillData: fill.fillData,
 | 
			
		||||
        fillData: createFinalBridgeOrderFillDataFromCollapsedFill(fill),
 | 
			
		||||
        source: fill.source,
 | 
			
		||||
        sourcePathId: fill.sourcePathId,
 | 
			
		||||
        type: FillQuoteTransformerOrderType.Bridge,
 | 
			
		||||
@@ -264,6 +300,36 @@ export function createBridgeOrder(
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function createFinalBridgeOrderFillDataFromCollapsedFill(fill: CollapsedFill): FillData {
 | 
			
		||||
    switch (fill.source) {
 | 
			
		||||
        case ERC20BridgeSource.UniswapV3: {
 | 
			
		||||
            const fd = fill.fillData as UniswapV3FillData;
 | 
			
		||||
            return {
 | 
			
		||||
                router: fd.router,
 | 
			
		||||
                tokenAddressPath: fd.tokenAddressPath,
 | 
			
		||||
                uniswapPath: getBestUniswapV3PathForInputAmount(fd, fill.input),
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    return fill.fillData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getBestUniswapV3PathForInputAmount(fillData: UniswapV3FillData, inputAmount: BigNumber): string {
 | 
			
		||||
    if (fillData.pathAmounts.length === 0) {
 | 
			
		||||
        throw new Error(`No Uniswap V3 paths`);
 | 
			
		||||
    }
 | 
			
		||||
    // Find the best path that can satisfy `inputAmount`.
 | 
			
		||||
    // Assumes `fillData.pathAmounts` is sorted ascending.
 | 
			
		||||
    for (const { inputAmount: pathInputAmount, uniswapPath } of fillData.pathAmounts) {
 | 
			
		||||
        if (pathInputAmount.gte(inputAmount)) {
 | 
			
		||||
            return uniswapPath;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return fillData.pathAmounts[fillData.pathAmounts.length - 1].uniswapPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getMakerTakerTokens(opts: CreateOrderFromPathOpts): [string, string] {
 | 
			
		||||
    const makerToken = opts.side === MarketOperation.Sell ? opts.outputToken : opts.inputToken;
 | 
			
		||||
    const takerToken = opts.side === MarketOperation.Sell ? opts.inputToken : opts.outputToken;
 | 
			
		||||
@@ -281,6 +347,7 @@ const makerPsmEncoder = AbiEncoder.create([
 | 
			
		||||
    { name: 'psmAddress', type: 'address' },
 | 
			
		||||
    { name: 'gemTokenAddress', type: 'address' },
 | 
			
		||||
]);
 | 
			
		||||
const balancerV2Encoder = AbiEncoder.create([{ name: 'vault', type: 'address' }, { name: 'poolId', type: 'bytes32' }]);
 | 
			
		||||
const routerAddressPathEncoder = AbiEncoder.create('(address,address[])');
 | 
			
		||||
const tokenAddressEncoder = AbiEncoder.create([{ name: 'tokenAddress', type: 'address' }]);
 | 
			
		||||
 | 
			
		||||
@@ -316,6 +383,7 @@ export const BRIDGE_ENCODERS: {
 | 
			
		||||
    [ERC20BridgeSource.Ellipsis]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Smoothy]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Saddle]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.XSigma]: curveEncoder,
 | 
			
		||||
    // UniswapV2 like, (router, address[])
 | 
			
		||||
    [ERC20BridgeSource.Bancor]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.UniswapV2]: routerAddressPathEncoder,
 | 
			
		||||
@@ -323,6 +391,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,
 | 
			
		||||
@@ -334,10 +410,11 @@ export const BRIDGE_ENCODERS: {
 | 
			
		||||
    [ERC20BridgeSource.Uniswap]: poolEncoder,
 | 
			
		||||
    // Custom integrations
 | 
			
		||||
    [ERC20BridgeSource.MakerPsm]: makerPsmEncoder,
 | 
			
		||||
    // BSC
 | 
			
		||||
    [ERC20BridgeSource.PancakeSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.BakerySwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.PancakeSwapV2]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: balancerV2Encoder,
 | 
			
		||||
    [ERC20BridgeSource.UniswapV3]: AbiEncoder.create([
 | 
			
		||||
        { name: 'router', type: 'address' },
 | 
			
		||||
        { name: 'path', type: 'bytes' },
 | 
			
		||||
    ]),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,149 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
/**
 | 
			
		||||
 * This has been copied from https://github.com/balancer-labs/balancer-sor/blob/john/rc2/src/helpers.ts.
 | 
			
		||||
 * Still awaiting V2 support for @balancer-labs/sor, once full V2 support is shipped we can upgrade sor and delete this file
 | 
			
		||||
 */
 | 
			
		||||
export const parsePoolData = (
 | 
			
		||||
    directPools: SubGraphPoolDictionary,
 | 
			
		||||
    tokenIn: string,
 | 
			
		||||
    tokenOut: string,
 | 
			
		||||
    mostLiquidPoolsFirstHop: SubGraphPool[] = [],
 | 
			
		||||
    mostLiquidPoolsSecondHop: SubGraphPool[] = [],
 | 
			
		||||
    hopTokens: string[] = [],
 | 
			
		||||
): [SubGraphPoolDictionary, Path[]] => {
 | 
			
		||||
    const pathDataList: Path[] = [];
 | 
			
		||||
    const pools: SubGraphPoolDictionary = {};
 | 
			
		||||
 | 
			
		||||
    // First add direct pair paths
 | 
			
		||||
    // tslint:disable-next-line:forin
 | 
			
		||||
    for (const idKey in directPools) {
 | 
			
		||||
        const p: SubGraphPool = directPools[idKey];
 | 
			
		||||
        // Add pool to the set with all pools (only adds if it's still not present in dict)
 | 
			
		||||
        pools[idKey] = p;
 | 
			
		||||
 | 
			
		||||
        const swap: Swap = {
 | 
			
		||||
            pool: p.id,
 | 
			
		||||
            tokenIn,
 | 
			
		||||
            tokenOut,
 | 
			
		||||
            tokenInDecimals: 18, // Placeholder for actual decimals
 | 
			
		||||
            tokenOutDecimals: 18,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const path: Path = {
 | 
			
		||||
            id: p.id,
 | 
			
		||||
            swaps: [swap],
 | 
			
		||||
        };
 | 
			
		||||
        pathDataList.push(path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Now add multi-hop paths.
 | 
			
		||||
    // mostLiquidPoolsFirstHop and mostLiquidPoolsSecondHop always has the same
 | 
			
		||||
    // lengh of hopTokens
 | 
			
		||||
    for (let i = 0; i < hopTokens.length; i++) {
 | 
			
		||||
        // Add pools to the set with all pools (only adds if it's still not present in dict)
 | 
			
		||||
        pools[mostLiquidPoolsFirstHop[i].id] = mostLiquidPoolsFirstHop[i];
 | 
			
		||||
        pools[mostLiquidPoolsSecondHop[i].id] = mostLiquidPoolsSecondHop[i];
 | 
			
		||||
 | 
			
		||||
        const swap1: Swap = {
 | 
			
		||||
            pool: mostLiquidPoolsFirstHop[i].id,
 | 
			
		||||
            tokenIn,
 | 
			
		||||
            tokenOut: hopTokens[i],
 | 
			
		||||
            tokenInDecimals: 18, // Placeholder for actual decimals
 | 
			
		||||
            tokenOutDecimals: 18,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const swap2: Swap = {
 | 
			
		||||
            pool: mostLiquidPoolsSecondHop[i].id,
 | 
			
		||||
            tokenIn: hopTokens[i],
 | 
			
		||||
            tokenOut,
 | 
			
		||||
            tokenInDecimals: 18, // Placeholder for actual decimals
 | 
			
		||||
            tokenOutDecimals: 18,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const path: Path = {
 | 
			
		||||
            id: mostLiquidPoolsFirstHop[i].id + mostLiquidPoolsSecondHop[i].id, // Path id is the concatenation of the ids of poolFirstHop and poolSecondHop
 | 
			
		||||
            swaps: [swap1, swap2],
 | 
			
		||||
        };
 | 
			
		||||
        pathDataList.push(path);
 | 
			
		||||
    }
 | 
			
		||||
    return [pools, pathDataList];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface SubGraphPool {
 | 
			
		||||
    id: string;
 | 
			
		||||
    swapFee: string;
 | 
			
		||||
    totalWeight: string;
 | 
			
		||||
    totalShares: string;
 | 
			
		||||
    tokens: SubGraphToken[];
 | 
			
		||||
    tokensList: string[];
 | 
			
		||||
    poolType?: string;
 | 
			
		||||
 | 
			
		||||
    // Only for stable pools
 | 
			
		||||
    amp: string;
 | 
			
		||||
 | 
			
		||||
    // Only for element pools
 | 
			
		||||
    lpShares?: BigNumber;
 | 
			
		||||
    time?: BigNumber;
 | 
			
		||||
    principalToken?: string;
 | 
			
		||||
    baseToken?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface SubGraphPoolDictionary {
 | 
			
		||||
    [poolId: string]: SubGraphPool;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface SubGraphToken {
 | 
			
		||||
    address: string;
 | 
			
		||||
    balance: string;
 | 
			
		||||
    decimals: string | number;
 | 
			
		||||
    // Stable & Element field
 | 
			
		||||
    weight?: string;
 | 
			
		||||
}
 | 
			
		||||
interface Path {
 | 
			
		||||
    id: string; // pool address if direct path, contactenation of pool addresses if multihop
 | 
			
		||||
    swaps: Swap[];
 | 
			
		||||
    poolPairData?: PoolPairData[];
 | 
			
		||||
    limitAmount?: BigNumber;
 | 
			
		||||
    filterEffectivePrice?: BigNumber; // TODO: This is just used for filtering, maybe there is a better way to filter?
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Swap {
 | 
			
		||||
    pool: string;
 | 
			
		||||
    tokenIn: string;
 | 
			
		||||
    tokenOut: string;
 | 
			
		||||
    swapAmount?: string;
 | 
			
		||||
    limitReturnAmount?: string;
 | 
			
		||||
    maxPrice?: string;
 | 
			
		||||
    tokenInDecimals: number;
 | 
			
		||||
    tokenOutDecimals: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PoolPairData {
 | 
			
		||||
    id: string;
 | 
			
		||||
    poolType?: string; // Todo: make this a mandatory field?
 | 
			
		||||
    pairType?: string; // Todo: make this a mandatory field?
 | 
			
		||||
    tokenIn: string;
 | 
			
		||||
    tokenOut: string;
 | 
			
		||||
    balanceIn?: BigNumber;
 | 
			
		||||
    balanceOut?: BigNumber;
 | 
			
		||||
    decimalsIn: number;
 | 
			
		||||
    decimalsOut: number;
 | 
			
		||||
    swapFee: BigNumber;
 | 
			
		||||
 | 
			
		||||
    // For weighted & element pools
 | 
			
		||||
    weightIn?: BigNumber;
 | 
			
		||||
    weightOut?: BigNumber;
 | 
			
		||||
 | 
			
		||||
    // Only for stable pools
 | 
			
		||||
    allBalances: BigNumber[];
 | 
			
		||||
    invariant?: BigNumber;
 | 
			
		||||
    amp?: BigNumber;
 | 
			
		||||
    tokenIndexIn?: number;
 | 
			
		||||
    tokenIndexOut?: number;
 | 
			
		||||
 | 
			
		||||
    // Only for element pools
 | 
			
		||||
    lpShares?: BigNumber;
 | 
			
		||||
    time?: BigNumber;
 | 
			
		||||
    principalToken?: string;
 | 
			
		||||
    baseToken?: string;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,107 @@
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from '@balancer-labs/sor';
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { gql, request } from 'graphql-request';
 | 
			
		||||
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_SUBGRAPH_URL, BALANCER_TOP_POOLS_FETCHED } from '../constants';
 | 
			
		||||
 | 
			
		||||
import { CacheValue, PoolsCache } from './pools_cache';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:custom-no-magic-numbers
 | 
			
		||||
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
 | 
			
		||||
// tslint:enable:custom-no-magic-numbers
 | 
			
		||||
 | 
			
		||||
interface BalancerPoolResponse {
 | 
			
		||||
    id: string;
 | 
			
		||||
    swapFee: string;
 | 
			
		||||
    tokens: Array<{ address: string; decimals: number; balance: string }>;
 | 
			
		||||
    tokensList: string[];
 | 
			
		||||
    totalWeight: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class BalancerPoolsCache extends PoolsCache {
 | 
			
		||||
    constructor(
 | 
			
		||||
        private readonly _subgraphUrl: string = BALANCER_SUBGRAPH_URL,
 | 
			
		||||
        cache: { [key: string]: CacheValue } = {},
 | 
			
		||||
        private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
 | 
			
		||||
        private readonly _topPoolsFetched: number = BALANCER_TOP_POOLS_FETCHED,
 | 
			
		||||
    ) {
 | 
			
		||||
        super(cache);
 | 
			
		||||
        void this._loadTopPoolsAsync();
 | 
			
		||||
        // Reload the top pools every 12 hours
 | 
			
		||||
        setInterval(async () => void this._loadTopPoolsAsync(), ONE_DAY_MS / 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
        try {
 | 
			
		||||
            const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
 | 
			
		||||
            // Sort by maker token balance (descending)
 | 
			
		||||
            const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
 | 
			
		||||
                b.balanceOut.minus(a.balanceOut).toNumber(),
 | 
			
		||||
            );
 | 
			
		||||
            return pools.length > this.maxPoolsFetched ? pools.slice(0, this.maxPoolsFetched) : pools;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _loadTopPoolsAsync(): Promise<void> {
 | 
			
		||||
        const fromToPools: {
 | 
			
		||||
            [from: string]: { [to: string]: Pool[] };
 | 
			
		||||
        } = {};
 | 
			
		||||
 | 
			
		||||
        const pools = await this._fetchTopPoolsAsync();
 | 
			
		||||
        for (const pool of pools) {
 | 
			
		||||
            const { tokensList } = pool;
 | 
			
		||||
            for (const from of tokensList) {
 | 
			
		||||
                for (const to of tokensList.filter(t => t.toLowerCase() !== from.toLowerCase())) {
 | 
			
		||||
                    fromToPools[from] = fromToPools[from] || {};
 | 
			
		||||
                    fromToPools[from][to] = fromToPools[from][to] || [];
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        // The list of pools must be relevant to `from` and `to`  for `parsePoolData`
 | 
			
		||||
                        const poolData = parsePoolData([pool], from, to);
 | 
			
		||||
                        fromToPools[from][to].push(poolData[0]);
 | 
			
		||||
                        // Cache this as we progress through
 | 
			
		||||
                        const expiresAt = Date.now() + this._cacheTimeMs;
 | 
			
		||||
                        this._cachePoolsForPair(from, to, fromToPools[from][to], expiresAt);
 | 
			
		||||
                    } catch {
 | 
			
		||||
                        // soldier on
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _fetchTopPoolsAsync(): Promise<BalancerPoolResponse[]> {
 | 
			
		||||
        const query = gql`
 | 
			
		||||
            query fetchTopPools($topPoolsFetched: Int!) {
 | 
			
		||||
                pools(
 | 
			
		||||
                    first: $topPoolsFetched
 | 
			
		||||
                    where: { publicSwap: true, liquidity_gt: 0 }
 | 
			
		||||
                    orderBy: swapsCount
 | 
			
		||||
                    orderDirection: desc
 | 
			
		||||
                ) {
 | 
			
		||||
                    id
 | 
			
		||||
                    publicSwap
 | 
			
		||||
                    swapFee
 | 
			
		||||
                    totalWeight
 | 
			
		||||
                    tokensList
 | 
			
		||||
                    tokens {
 | 
			
		||||
                        id
 | 
			
		||||
                        address
 | 
			
		||||
                        balance
 | 
			
		||||
                        decimals
 | 
			
		||||
                        symbol
 | 
			
		||||
                        denormWeight
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        `;
 | 
			
		||||
        try {
 | 
			
		||||
            const { pools } = await request(this._subgraphUrl, query, { topPoolsFetched: this._topPoolsFetched });
 | 
			
		||||
            return pools;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,172 @@
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
// import { parsePoolData } from '@balancer-labs'; // TODO - upgrade to v2
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { gql, request } from 'graphql-request';
 | 
			
		||||
 | 
			
		||||
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
 | 
			
		||||
import { LogFunction } from '../../../types';
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_TOP_POOLS_FETCHED, BALANCER_V2_SUBGRAPH_URL } from '../constants';
 | 
			
		||||
 | 
			
		||||
import { parsePoolData } from './balancer_sor_v2';
 | 
			
		||||
import { CacheValue, PoolsCache } from './pools_cache';
 | 
			
		||||
 | 
			
		||||
// tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
 | 
			
		||||
 | 
			
		||||
interface BalancerPoolResponse {
 | 
			
		||||
    id: string;
 | 
			
		||||
    swapFee: string;
 | 
			
		||||
    tokens: Array<{ address: string; decimals: number; balance: string; weight: string; symbol: string }>;
 | 
			
		||||
    tokensList: string[];
 | 
			
		||||
    totalWeight: string;
 | 
			
		||||
    totalShares: string;
 | 
			
		||||
    amp: string | null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class BalancerV2PoolsCache extends PoolsCache {
 | 
			
		||||
    private static _parseSubgraphPoolData(pool: any, takerToken: string, makerToken: string): Pool {
 | 
			
		||||
        const tToken = pool.tokens.find((t: any) => t.address === takerToken);
 | 
			
		||||
        const mToken = pool.tokens.find((t: any) => t.address === makerToken);
 | 
			
		||||
        const swap = pool.swaps && pool.swaps[0];
 | 
			
		||||
        const tokenAmountOut = swap ? swap.tokenAmountOut : undefined;
 | 
			
		||||
        const tokenAmountIn = swap ? swap.tokenAmountIn : undefined;
 | 
			
		||||
        const spotPrice =
 | 
			
		||||
            tokenAmountOut && tokenAmountIn ? new BigNumber(tokenAmountOut).div(tokenAmountIn) : undefined; // TODO: xianny check
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            id: pool.id,
 | 
			
		||||
            balanceIn: new BigNumber(tToken.balance),
 | 
			
		||||
            balanceOut: new BigNumber(mToken.balance),
 | 
			
		||||
            weightIn: new BigNumber(tToken.weight),
 | 
			
		||||
            weightOut: new BigNumber(mToken.weight),
 | 
			
		||||
            swapFee: new BigNumber(pool.swapFee),
 | 
			
		||||
            spotPrice,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private readonly subgraphUrl: string = BALANCER_V2_SUBGRAPH_URL,
 | 
			
		||||
        private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
 | 
			
		||||
        private readonly _topPoolsFetched: number = BALANCER_TOP_POOLS_FETCHED,
 | 
			
		||||
        private readonly _warningLogger: LogFunction = DEFAULT_WARNING_LOGGER,
 | 
			
		||||
        cache: { [key: string]: CacheValue } = {},
 | 
			
		||||
    ) {
 | 
			
		||||
        super(cache);
 | 
			
		||||
        void this._loadTopPoolsAsync();
 | 
			
		||||
        // Reload the top pools every 12 hours
 | 
			
		||||
        setInterval(async () => void this._loadTopPoolsAsync(), ONE_DAY_MS / 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
    //     try {
 | 
			
		||||
    //         const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
 | 
			
		||||
    //         // Sort by maker token balance (descending)
 | 
			
		||||
    //         const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
 | 
			
		||||
    //             b.balanceOut.minus(a.balanceOut).toNumber(),
 | 
			
		||||
    //         );
 | 
			
		||||
    //         return pools.length > this.maxPoolsFetched ? pools.slice(0, this.maxPoolsFetched) : pools;
 | 
			
		||||
    //     } catch (err) {
 | 
			
		||||
    //         return [];
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    protected async _fetchTopPoolsAsync(): Promise<BalancerPoolResponse[]> {
 | 
			
		||||
        const query = gql`
 | 
			
		||||
            query fetchTopPools($topPoolsFetched: Int!) {
 | 
			
		||||
                pools(
 | 
			
		||||
                    first: $topPoolsFetched
 | 
			
		||||
                    where: { totalLiquidity_gt: 0 }
 | 
			
		||||
                    orderBy: swapsCount
 | 
			
		||||
                    orderDirection: desc
 | 
			
		||||
                ) {
 | 
			
		||||
                    id
 | 
			
		||||
                    swapFee
 | 
			
		||||
                    totalWeight
 | 
			
		||||
                    tokensList
 | 
			
		||||
                    amp
 | 
			
		||||
                    totalShares
 | 
			
		||||
                    tokens {
 | 
			
		||||
                        id
 | 
			
		||||
                        address
 | 
			
		||||
                        balance
 | 
			
		||||
                        decimals
 | 
			
		||||
                        symbol
 | 
			
		||||
                        weight
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        `;
 | 
			
		||||
 | 
			
		||||
        const { pools } = await request<{ pools: BalancerPoolResponse[] }>(this.subgraphUrl, query, {
 | 
			
		||||
            topPoolsFetched: this._topPoolsFetched,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return pools;
 | 
			
		||||
    }
 | 
			
		||||
    protected async _loadTopPoolsAsync(): Promise<void> {
 | 
			
		||||
        const fromToPools: {
 | 
			
		||||
            [from: string]: { [to: string]: Pool[] };
 | 
			
		||||
        } = {};
 | 
			
		||||
 | 
			
		||||
        const pools = await this._fetchTopPoolsAsync();
 | 
			
		||||
        for (const pool of pools) {
 | 
			
		||||
            const { tokensList } = pool;
 | 
			
		||||
            for (const from of tokensList) {
 | 
			
		||||
                for (const to of tokensList.filter(t => t.toLowerCase() !== from.toLowerCase())) {
 | 
			
		||||
                    fromToPools[from] = fromToPools[from] || {};
 | 
			
		||||
                    fromToPools[from][to] = fromToPools[from][to] || [];
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        // The list of pools must be relevant to `from` and `to`  for `parsePoolData`
 | 
			
		||||
                        const [poolData] = parsePoolData({ [pool.id]: pool as any }, from, to);
 | 
			
		||||
                        fromToPools[from][to].push(
 | 
			
		||||
                            BalancerV2PoolsCache._parseSubgraphPoolData(poolData[pool.id], from, to),
 | 
			
		||||
                        );
 | 
			
		||||
                        // Cache this as we progress through
 | 
			
		||||
                        const expiresAt = Date.now() + this._cacheTimeMs;
 | 
			
		||||
                        this._cachePoolsForPair(from, to, fromToPools[from][to], expiresAt);
 | 
			
		||||
                    } catch (err) {
 | 
			
		||||
                        this._warningLogger(err, `Failed to load Balancer V2 top pools`);
 | 
			
		||||
                        // soldier on
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
        const query = gql`
 | 
			
		||||
        query getPools {
 | 
			
		||||
            pools(
 | 
			
		||||
              first: ${this.maxPoolsFetched},
 | 
			
		||||
              where: {
 | 
			
		||||
                tokensList_contains: ["${takerToken}", "${makerToken}"]
 | 
			
		||||
              }
 | 
			
		||||
            ) {
 | 
			
		||||
                id
 | 
			
		||||
                tokens {
 | 
			
		||||
                    address
 | 
			
		||||
                    balance
 | 
			
		||||
                    weight
 | 
			
		||||
                }
 | 
			
		||||
              swapFee
 | 
			
		||||
              swaps(
 | 
			
		||||
                orderBy: timestamp, orderDirection: desc, first: 1,
 | 
			
		||||
                  where:{
 | 
			
		||||
                  tokenIn: "${takerToken}",
 | 
			
		||||
                  tokenOut: "${makerToken}"
 | 
			
		||||
                }
 | 
			
		||||
              ) {
 | 
			
		||||
                tokenAmountIn
 | 
			
		||||
                tokenAmountOut
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          `;
 | 
			
		||||
        try {
 | 
			
		||||
            const { pools } = await request(this.subgraphUrl, query);
 | 
			
		||||
            return pools.map((pool: any) => BalancerV2PoolsCache._parseSubgraphPoolData(pool, takerToken, makerToken));
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from 'cream-sor';
 | 
			
		||||
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED } from '../constants';
 | 
			
		||||
 | 
			
		||||
import { CacheValue, PoolsCache } from './pools_cache';
 | 
			
		||||
 | 
			
		||||
export class CreamPoolsCache extends PoolsCache {
 | 
			
		||||
    constructor(
 | 
			
		||||
        _cache: { [key: string]: CacheValue } = {},
 | 
			
		||||
        private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
 | 
			
		||||
    ) {
 | 
			
		||||
        super(_cache);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
        try {
 | 
			
		||||
            const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
 | 
			
		||||
            // Sort by maker token balance (descending)
 | 
			
		||||
            const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
 | 
			
		||||
                b.balanceOut.minus(a.balanceOut).toNumber(),
 | 
			
		||||
            );
 | 
			
		||||
            return pools.slice(0, this.maxPoolsFetched);
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
export { BalancerPoolsCache } from './balancer_utils';
 | 
			
		||||
export { BalancerV2PoolsCache } from './balancer_v2_utils';
 | 
			
		||||
export { CreamPoolsCache } from './cream_utils';
 | 
			
		||||
export { PoolsCache } from './pools_cache';
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
 | 
			
		||||
import { ONE_HOUR_IN_SECONDS, ONE_SECOND_MS } from '../constants';
 | 
			
		||||
export { Pool };
 | 
			
		||||
export interface CacheValue {
 | 
			
		||||
    expiresAt: number;
 | 
			
		||||
    pools: Pool[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tslint:disable:custom-no-magic-numbers
 | 
			
		||||
// Cache results for 30mins
 | 
			
		||||
const DEFAULT_CACHE_TIME_MS = (ONE_HOUR_IN_SECONDS / 2) * ONE_SECOND_MS;
 | 
			
		||||
const DEFAULT_TIMEOUT_MS = 1000;
 | 
			
		||||
// tslint:enable:custom-no-magic-numbers
 | 
			
		||||
 | 
			
		||||
export abstract class PoolsCache {
 | 
			
		||||
    protected static _isExpired(value: CacheValue): boolean {
 | 
			
		||||
        return Date.now() >= value.expiresAt;
 | 
			
		||||
    }
 | 
			
		||||
    constructor(
 | 
			
		||||
        protected readonly _cache: { [key: string]: CacheValue },
 | 
			
		||||
        protected readonly _cacheTimeMs: number = DEFAULT_CACHE_TIME_MS,
 | 
			
		||||
    ) {}
 | 
			
		||||
 | 
			
		||||
    public async getFreshPoolsForPairAsync(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        timeoutMs: number = DEFAULT_TIMEOUT_MS,
 | 
			
		||||
    ): Promise<Pool[]> {
 | 
			
		||||
        const timeout = new Promise<Pool[]>(resolve => setTimeout(resolve, timeoutMs, []));
 | 
			
		||||
        return Promise.race([this._getAndSaveFreshPoolsForPairAsync(takerToken, makerToken), timeout]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getCachedPoolAddressesForPair(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        ignoreExpired: boolean = true,
 | 
			
		||||
    ): string[] | undefined {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        if (ignoreExpired) {
 | 
			
		||||
            return value === undefined ? [] : value.pools.map(pool => pool.id);
 | 
			
		||||
        }
 | 
			
		||||
        if (!value) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        if (PoolsCache._isExpired(value)) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        return (value || []).pools.map(pool => pool.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public isFresh(takerToken: string, makerToken: string): boolean {
 | 
			
		||||
        const cached = this.getCachedPoolAddressesForPair(takerToken, makerToken, false);
 | 
			
		||||
        return cached !== undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _getAndSaveFreshPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        if (value === undefined || value.expiresAt >= Date.now()) {
 | 
			
		||||
            const pools = await this._fetchPoolsForPairAsync(takerToken, makerToken);
 | 
			
		||||
            const expiresAt = Date.now() + this._cacheTimeMs;
 | 
			
		||||
            this._cachePoolsForPair(takerToken, makerToken, pools, expiresAt);
 | 
			
		||||
        }
 | 
			
		||||
        return this._cache[key].pools;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected _cachePoolsForPair(takerToken: string, makerToken: string, pools: Pool[], expiresAt: number): void {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        this._cache[key] = {
 | 
			
		||||
            pools,
 | 
			
		||||
            expiresAt,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]>;
 | 
			
		||||
}
 | 
			
		||||
@@ -4,11 +4,10 @@ import { BigNumber, NULL_BYTES } from '@0x/utils';
 | 
			
		||||
import { SamplerOverrides } from '../../types';
 | 
			
		||||
import { ERC20BridgeSamplerContract } from '../../wrappers';
 | 
			
		||||
 | 
			
		||||
import { BalancerPoolsCache } from './balancer_utils';
 | 
			
		||||
import { BancorService } from './bancor_service';
 | 
			
		||||
import { CreamPoolsCache } from './cream_utils';
 | 
			
		||||
import { PoolsCache } from './pools_cache';
 | 
			
		||||
import { SamplerOperations } from './sampler_operations';
 | 
			
		||||
import { BatchedOperation, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
 | 
			
		||||
import { BatchedOperation, ERC20BridgeSource, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate sample amounts up to `maxFillAmount`.
 | 
			
		||||
@@ -37,21 +36,12 @@ export class DexOrderSampler extends SamplerOperations {
 | 
			
		||||
        public readonly chainId: ChainId,
 | 
			
		||||
        _samplerContract: ERC20BridgeSamplerContract,
 | 
			
		||||
        private readonly _samplerOverrides?: SamplerOverrides,
 | 
			
		||||
        balancerPoolsCache?: BalancerPoolsCache,
 | 
			
		||||
        creamPoolsCache?: CreamPoolsCache,
 | 
			
		||||
        poolsCaches?: { [key in ERC20BridgeSource]: PoolsCache },
 | 
			
		||||
        tokenAdjacencyGraph?: TokenAdjacencyGraph,
 | 
			
		||||
        liquidityProviderRegistry?: LiquidityProviderRegistry,
 | 
			
		||||
        bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
 | 
			
		||||
    ) {
 | 
			
		||||
        super(
 | 
			
		||||
            chainId,
 | 
			
		||||
            _samplerContract,
 | 
			
		||||
            balancerPoolsCache,
 | 
			
		||||
            creamPoolsCache,
 | 
			
		||||
            tokenAdjacencyGraph,
 | 
			
		||||
            liquidityProviderRegistry,
 | 
			
		||||
            bancorServiceFn,
 | 
			
		||||
        );
 | 
			
		||||
        super(chainId, _samplerContract, poolsCaches, tokenAdjacencyGraph, liquidityProviderRegistry, bancorServiceFn);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Type overloads for `executeAsync()`. Could skip this if we would upgrade TS. */
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user