Compare commits
	
		
			107 Commits
		
	
	
		
			protocol@c
			...
			protocol@f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					f0738fc122 | ||
| 
						 | 
					42baf504b7 | ||
| 
						 | 
					56038d122f | ||
| 
						 | 
					c4446b6c0e | ||
| 
						 | 
					eaed2958c3 | ||
| 
						 | 
					a045a3afb8 | ||
| 
						 | 
					1cc59ab1ab | ||
| 
						 | 
					2c6a714b71 | ||
| 
						 | 
					d8c97d6720 | ||
| 
						 | 
					d6bc702550 | ||
| 
						 | 
					2838cb9420 | ||
| 
						 | 
					b10cfc50d3 | ||
| 
						 | 
					2e6317b01e | ||
| 
						 | 
					50e99e6eac | ||
| 
						 | 
					8f2f4554eb | ||
| 
						 | 
					67d9678a3a | ||
| 
						 | 
					f70341fb48 | ||
| 
						 | 
					14cd24ea47 | ||
| 
						 | 
					78328056d7 | ||
| 
						 | 
					0045a60b0f | ||
| 
						 | 
					e4e71c76e1 | ||
| 
						 | 
					ca8127545f | ||
| 
						 | 
					7b709089ce | ||
| 
						 | 
					190f7e45f2 | ||
| 
						 | 
					0dcc3a6fc3 | ||
| 
						 | 
					c2e8cae293 | ||
| 
						 | 
					83da7caab4 | ||
| 
						 | 
					fd69a0c273 | ||
| 
						 | 
					9b131199ad | ||
| 
						 | 
					f5c486050b | ||
| 
						 | 
					1f41fe6a20 | ||
| 
						 | 
					7f4080e0a2 | ||
| 
						 | 
					db76da58d7 | ||
| 
						 | 
					cf8fc0ff8e | ||
| 
						 | 
					2d16f83e37 | ||
| 
						 | 
					4057bdab91 | ||
| 
						 | 
					1cd10f0ac9 | ||
| 
						 | 
					68f87b2432 | ||
| 
						 | 
					69bafc3bcd | ||
| 
						 | 
					2c44b06b7b | ||
| 
						 | 
					0233f00b4e | ||
| 
						 | 
					fedb53187d | ||
| 
						 | 
					6774d2f588 | ||
| 
						 | 
					cf740b74f5 | ||
| 
						 | 
					177c00463a | ||
| 
						 | 
					49b0e32129 | ||
| 
						 | 
					938fc94756 | ||
| 
						 | 
					1561d91c2b | ||
| 
						 | 
					9a28e51f51 | ||
| 
						 | 
					f55eaa867b | ||
| 
						 | 
					6b2856424a | ||
| 
						 | 
					da757c4700 | ||
| 
						 | 
					75e6654884 | ||
| 
						 | 
					87308e7693 | ||
| 
						 | 
					d5eef93a76 | ||
| 
						 | 
					a7f23a982e | ||
| 
						 | 
					9eadc5fc28 | ||
| 
						 | 
					92ad1a612e | ||
| 
						 | 
					09413c0e12 | ||
| 
						 | 
					23788b41d5 | ||
| 
						 | 
					ccf999a495 | ||
| 
						 | 
					aa1016ee5f | ||
| 
						 | 
					423ef57344 | ||
| 
						 | 
					c18149e82f | ||
| 
						 | 
					d14aebf724 | ||
| 
						 | 
					ba719a9631 | ||
| 
						 | 
					d36034d958 | ||
| 
						 | 
					7750c57620 | ||
| 
						 | 
					4d027e11d1 | ||
| 
						 | 
					470e9a4697 | ||
| 
						 | 
					7c51412e2f | ||
| 
						 | 
					b3d1f3cd10 | ||
| 
						 | 
					389bb77439 | ||
| 
						 | 
					4327885a00 | ||
| 
						 | 
					0aef0afbbb | ||
| 
						 | 
					fa4c3a4f5f | ||
| 
						 | 
					1d7c527c5c | ||
| 
						 | 
					cbe3135e4b | ||
| 
						 | 
					955ad49711 | ||
| 
						 | 
					8d6f6e76e0 | ||
| 
						 | 
					9337115650 | ||
| 
						 | 
					fa45a44fe4 | ||
| 
						 | 
					c9c7ac8559 | ||
| 
						 | 
					c881723578 | ||
| 
						 | 
					c9c30d3a76 | ||
| 
						 | 
					73dfdb5b69 | ||
| 
						 | 
					e638268f94 | ||
| 
						 | 
					0bfd765481 | ||
| 
						 | 
					1f12893735 | ||
| 
						 | 
					dd3d9337c4 | ||
| 
						 | 
					904214f4a8 | ||
| 
						 | 
					64c090c4b4 | ||
| 
						 | 
					e24474f152 | ||
| 
						 | 
					29fa408256 | ||
| 
						 | 
					1b94cc68af | ||
| 
						 | 
					f5b4bb3035 | ||
| 
						 | 
					afd880f28c | ||
| 
						 | 
					cd14cdd168 | ||
| 
						 | 
					c8ff53a75f | ||
| 
						 | 
					6d08add20b | ||
| 
						 | 
					29f9c725e3 | ||
| 
						 | 
					a83453f07f | ||
| 
						 | 
					ae365ce92c | ||
| 
						 | 
					77a592e891 | ||
| 
						 | 
					9a1df67d6b | ||
| 
						 | 
					4b91411faf | ||
| 
						 | 
					622a542d57 | 
@@ -19,7 +19,6 @@ jobs:
 | 
			
		||||
                  command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
 | 
			
		||||
            - setup_remote_docker
 | 
			
		||||
            - run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci
 | 
			
		||||
            - run: yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts
 | 
			
		||||
            - save_cache:
 | 
			
		||||
                  key: repo-{{ .Environment.CIRCLE_SHA1 }}
 | 
			
		||||
                  paths:
 | 
			
		||||
@@ -110,6 +109,8 @@ jobs:
 | 
			
		||||
        docker:
 | 
			
		||||
            - image: node:16
 | 
			
		||||
        working_directory: ~/repo
 | 
			
		||||
        environment:
 | 
			
		||||
            RUST_ROUTER: 'true'
 | 
			
		||||
        steps:
 | 
			
		||||
            - restore_cache:
 | 
			
		||||
                  keys:
 | 
			
		||||
@@ -117,7 +118,6 @@ jobs:
 | 
			
		||||
            - 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:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/autolabeler.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,7 +1,6 @@
 | 
			
		||||
python: ['python-packages']
 | 
			
		||||
contracts: ['contracts']
 | 
			
		||||
@0x/contract-addresses: ['packages/contract-addresses']
 | 
			
		||||
@0x/migrations: ['packages/migrations']
 | 
			
		||||
@0x/order-utils: ['packages/order-utils']
 | 
			
		||||
@0x/contract-artifacts: ['packages/contract-artifacts']
 | 
			
		||||
@0x/contract-wrappers: ['packages/contract-wrappers']
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							@@ -28,7 +28,7 @@ jobs:
 | 
			
		||||
                fetch-depth: 0
 | 
			
		||||
            - uses: actions/setup-node@v1
 | 
			
		||||
              with:
 | 
			
		||||
                node-version: 10
 | 
			
		||||
                node-version: 16
 | 
			
		||||
            - uses: actions/setup-python@v2
 | 
			
		||||
            - name: 'configure git'
 | 
			
		||||
              run: |
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,6 @@ These packages are all under development. See [/contracts/README.md](/contracts/
 | 
			
		||||
| [`@0x/protocol-utils`](/packages/protocol-utils)         | [](https://www.npmjs.com/package/@0x/protocol-utils)         | A set of utilities for generating, parsing, signing and validating 0x orders                   |
 | 
			
		||||
| [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | A tiny utility library for getting known deployed contract addresses for a particular network. |
 | 
			
		||||
| [`@0x/contract-wrappers`](/packages/contract-wrappers)   | [](https://www.npmjs.com/package/@0x/contract-wrappers)   | JS/TS wrappers for interacting with the 0x smart contracts                                     |
 | 
			
		||||
| [`@0x/migrations`](/packages/migrations)                 | [](https://www.npmjs.com/package/@0x/migrations)                 | Migration tool for deploying 0x smart contracts on private testnets                            |
 | 
			
		||||
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts                                                        |  |
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,49 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1655244958,
 | 
			
		||||
        "version": "3.3.32",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1654284040,
 | 
			
		||||
        "version": "3.3.31",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1652919697,
 | 
			
		||||
        "version": "3.3.30",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1650611093,
 | 
			
		||||
        "version": "3.3.29",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1648739346,
 | 
			
		||||
        "version": "3.3.28",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1646225739,
 | 
			
		||||
        "version": "3.3.27",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v3.3.32 - _June 14, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.3.31 - _June 3, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.3.30 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.3.29 - _April 22, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.3.28 - _March 31, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v3.3.27 - _March 2, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-erc20",
 | 
			
		||||
    "version": "3.3.27",
 | 
			
		||||
    "version": "3.3.32",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -51,18 +51,18 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.7.2",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.43",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.18",
 | 
			
		||||
        "@0x/contracts-utils": "^4.8.8",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.11",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.8",
 | 
			
		||||
        "@0x/abi-gen": "^5.8.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.46",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.23",
 | 
			
		||||
        "@0x/contracts-utils": "^4.8.13",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.14",
 | 
			
		||||
        "@0x/sol-compiler": "^4.8.1",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.1",
 | 
			
		||||
        "@0x/utils": "^6.5.0",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.2",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@0x/typescript-typings": "^5.3.1",
 | 
			
		||||
        "@0x/utils": "^6.5.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.5",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -70,7 +70,7 @@
 | 
			
		||||
        "chai-as-promised": "^7.1.0",
 | 
			
		||||
        "chai-bignumber": "^3.0.0",
 | 
			
		||||
        "dirty-chai": "^2.0.1",
 | 
			
		||||
        "ethereum-types": "^3.6.0",
 | 
			
		||||
        "ethereum-types": "^3.7.0",
 | 
			
		||||
        "lodash": "^4.17.11",
 | 
			
		||||
        "make-promises-safe": "^1.1.0",
 | 
			
		||||
        "mocha": "^6.2.0",
 | 
			
		||||
@@ -79,10 +79,10 @@
 | 
			
		||||
        "solhint": "^1.4.1",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "~0.16.11",
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
        "typescript": "4.6.3"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.4.5",
 | 
			
		||||
        "@0x/base-contract": "^6.5.0",
 | 
			
		||||
        "ethers": "~4.0.4"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,49 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1655244958,
 | 
			
		||||
        "version": "5.4.23",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1654284040,
 | 
			
		||||
        "version": "5.4.22",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1652919697,
 | 
			
		||||
        "version": "5.4.21",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1650611093,
 | 
			
		||||
        "version": "5.4.20",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1648739346,
 | 
			
		||||
        "version": "5.4.19",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1646225739,
 | 
			
		||||
        "version": "5.4.18",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v5.4.23 - _June 14, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v5.4.22 - _June 3, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v5.4.21 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v5.4.20 - _April 22, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v5.4.19 - _March 31, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v5.4.18 - _March 2, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-test-utils",
 | 
			
		||||
    "version": "5.4.18",
 | 
			
		||||
    "version": "5.4.23",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -34,28 +34,28 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.8",
 | 
			
		||||
        "@0x/sol-compiler": "^4.8.1",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "npm-run-all": "^4.1.2",
 | 
			
		||||
        "shx": "^0.2.2",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
        "typescript": "4.6.3"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^3.0.31",
 | 
			
		||||
        "@0x/base-contract": "^6.4.5",
 | 
			
		||||
        "@0x/contract-addresses": "^6.12.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.11",
 | 
			
		||||
        "@0x/json-schemas": "^6.4.1",
 | 
			
		||||
        "@0x/assert": "^3.0.34",
 | 
			
		||||
        "@0x/base-contract": "^6.5.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.16.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.14",
 | 
			
		||||
        "@0x/json-schemas": "^6.4.4",
 | 
			
		||||
        "@0x/order-utils": "^10.4.28",
 | 
			
		||||
        "@0x/sol-coverage": "^4.0.42",
 | 
			
		||||
        "@0x/sol-profiler": "^4.1.32",
 | 
			
		||||
        "@0x/sol-trace": "^3.0.42",
 | 
			
		||||
        "@0x/subproviders": "^6.6.2",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.1",
 | 
			
		||||
        "@0x/utils": "^6.5.0",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.2",
 | 
			
		||||
        "@0x/sol-coverage": "^4.0.45",
 | 
			
		||||
        "@0x/sol-profiler": "^4.1.35",
 | 
			
		||||
        "@0x/sol-trace": "^3.0.45",
 | 
			
		||||
        "@0x/subproviders": "^6.6.5",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@0x/typescript-typings": "^5.3.1",
 | 
			
		||||
        "@0x/utils": "^6.5.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.5",
 | 
			
		||||
        "@types/bn.js": "^4.11.0",
 | 
			
		||||
        "@types/js-combinatorics": "^0.5.29",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
@@ -67,7 +67,7 @@
 | 
			
		||||
        "chai-bignumber": "^3.0.0",
 | 
			
		||||
        "decimal.js": "^10.2.0",
 | 
			
		||||
        "dirty-chai": "^2.0.1",
 | 
			
		||||
        "ethereum-types": "^3.6.0",
 | 
			
		||||
        "ethereum-types": "^3.7.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10",
 | 
			
		||||
        "ethers": "~4.0.4",
 | 
			
		||||
        "js-combinatorics": "^0.5.3",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,49 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1655244958,
 | 
			
		||||
        "version": "1.4.15",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1654284040,
 | 
			
		||||
        "version": "1.4.14",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1652919697,
 | 
			
		||||
        "version": "1.4.13",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1650611093,
 | 
			
		||||
        "version": "1.4.12",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1648739346,
 | 
			
		||||
        "version": "1.4.11",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1646225739,
 | 
			
		||||
        "version": "1.4.10",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v1.4.15 - _June 14, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.4.14 - _June 3, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.4.13 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.4.12 - _April 22, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.4.11 - _March 31, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v1.4.10 - _March 2, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-treasury",
 | 
			
		||||
    "version": "1.4.10",
 | 
			
		||||
    "version": "1.4.15",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -46,14 +46,14 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.7.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.12.0",
 | 
			
		||||
        "@0x/abi-gen": "^5.8.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.16.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.19",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.27",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.43",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.32",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.46",
 | 
			
		||||
        "@0x/contracts-staking": "^2.0.45",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.18",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.8",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.23",
 | 
			
		||||
        "@0x/sol-compiler": "^4.8.1",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@types/isomorphic-fetch": "^0.0.35",
 | 
			
		||||
@@ -69,17 +69,17 @@
 | 
			
		||||
        "solhint": "^1.4.1",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "~0.16.11",
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
        "typescript": "4.6.3"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.4.5",
 | 
			
		||||
        "@0x/protocol-utils": "^1.11.1",
 | 
			
		||||
        "@0x/subproviders": "^6.6.2",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.1",
 | 
			
		||||
        "@0x/utils": "^6.5.0",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.2",
 | 
			
		||||
        "ethereum-types": "^3.6.0",
 | 
			
		||||
        "@0x/base-contract": "^6.5.0",
 | 
			
		||||
        "@0x/protocol-utils": "^11.15.0",
 | 
			
		||||
        "@0x/subproviders": "^6.6.5",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@0x/typescript-typings": "^5.3.1",
 | 
			
		||||
        "@0x/utils": "^6.5.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.5",
 | 
			
		||||
        "ethereum-types": "^3.7.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,49 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1655244958,
 | 
			
		||||
        "version": "4.8.13",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1654284040,
 | 
			
		||||
        "version": "4.8.12",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1652919697,
 | 
			
		||||
        "version": "4.8.11",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1650611093,
 | 
			
		||||
        "version": "4.8.10",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1648739346,
 | 
			
		||||
        "version": "4.8.9",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1646225739,
 | 
			
		||||
        "version": "4.8.8",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v4.8.13 - _June 14, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.8.12 - _June 3, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.8.11 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.8.10 - _April 22, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.8.9 - _March 31, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v4.8.8 - _March 2, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-utils",
 | 
			
		||||
    "version": "4.8.8",
 | 
			
		||||
    "version": "4.8.13",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -50,15 +50,15 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.7.2",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.43",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.18",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.11",
 | 
			
		||||
        "@0x/abi-gen": "^5.8.0",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.46",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.23",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.14",
 | 
			
		||||
        "@0x/order-utils": "^10.4.28",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.8",
 | 
			
		||||
        "@0x/sol-compiler": "^4.8.1",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.2",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.5",
 | 
			
		||||
        "@types/bn.js": "^4.11.0",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
@@ -76,14 +76,14 @@
 | 
			
		||||
        "solhint": "^1.4.1",
 | 
			
		||||
        "truffle": "^5.0.32",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
        "typescript": "4.6.3"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.4.5",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.1",
 | 
			
		||||
        "@0x/utils": "^6.5.0",
 | 
			
		||||
        "@0x/base-contract": "^6.5.0",
 | 
			
		||||
        "@0x/typescript-typings": "^5.3.1",
 | 
			
		||||
        "@0x/utils": "^6.5.3",
 | 
			
		||||
        "bn.js": "^4.11.8",
 | 
			
		||||
        "ethereum-types": "^3.6.0"
 | 
			
		||||
        "ethereum-types": "^3.7.0"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,61 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "0.35.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Adds support for Velodrome OptimismBridgeAdapter",
 | 
			
		||||
                "pr": 494
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1655244958
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "0.34.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Splits BridgeAdapter up by chain",
 | 
			
		||||
                "pr": 487
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add stETH wrap/unwrap support",
 | 
			
		||||
                "pr": 476
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Adds support for BancorV3 to EthereumBridgeAdapter",
 | 
			
		||||
                "pr": 492
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1654284040
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "0.33.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add support for GMX and Platypus to bridge adapter",
 | 
			
		||||
                "pr": 478
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1652919697
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "0.32.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add support for `BalancerV2Batch` fills in FQT",
 | 
			
		||||
                "pr": 462
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1650611093
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1648739346,
 | 
			
		||||
        "version": "0.31.2",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Dependencies updated"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "timestamp": 1646225739,
 | 
			
		||||
        "version": "0.31.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,28 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v0.35.0 - _June 14, 2022_
 | 
			
		||||
 | 
			
		||||
    * Adds support for Velodrome OptimismBridgeAdapter (#494)
 | 
			
		||||
 | 
			
		||||
## v0.34.0 - _June 3, 2022_
 | 
			
		||||
 | 
			
		||||
    * Splits BridgeAdapter up by chain (#487)
 | 
			
		||||
    * Add stETH wrap/unwrap support (#476)
 | 
			
		||||
    * Adds support for BancorV3 to EthereumBridgeAdapter (#492)
 | 
			
		||||
 | 
			
		||||
## v0.33.0 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add support for GMX and Platypus to bridge adapter (#478)
 | 
			
		||||
 | 
			
		||||
## v0.32.0 - _April 22, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add support for `BalancerV2Batch` fills in FQT (#462)
 | 
			
		||||
 | 
			
		||||
## v0.31.2 - _March 31, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 | 
			
		||||
## v0.31.1 - _March 2, 2022_
 | 
			
		||||
 | 
			
		||||
    * Dependencies updated
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,88 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./IBridgeAdapter.sol";
 | 
			
		||||
 | 
			
		||||
abstract contract AbstractBridgeAdapter is IBridgeAdapter {
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        uint256 expectedChainId, 
 | 
			
		||||
        string memory expectedChainName
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
    {
 | 
			
		||||
        uint256 chainId;
 | 
			
		||||
        assembly { chainId := chainid() }
 | 
			
		||||
        // Allow testing on Ganache
 | 
			
		||||
        if (chainId != expectedChainId && chainId != 1337) {
 | 
			
		||||
            revert(string(abi.encodePacked(expectedChainName, "BridgeAdapter.constructor: wrong chain ID")));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function isSupportedSource(bytes32 source)
 | 
			
		||||
        external
 | 
			
		||||
        override
 | 
			
		||||
        returns (bool isSupported)
 | 
			
		||||
    {
 | 
			
		||||
        BridgeOrder memory placeholderOrder;
 | 
			
		||||
        placeholderOrder.source = source;
 | 
			
		||||
        IERC20TokenV06 placeholderToken = IERC20TokenV06(address(0));
 | 
			
		||||
        
 | 
			
		||||
        (, isSupported) = _trade(
 | 
			
		||||
            placeholderOrder,
 | 
			
		||||
            placeholderToken,
 | 
			
		||||
            placeholderToken,
 | 
			
		||||
            0,
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (boughtAmount, ) = _trade(
 | 
			
		||||
            order,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            false
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        virtual
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,141 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
import "./mixins/MixinCurveV2.sol";
 | 
			
		||||
import "./mixins/MixinGMX.sol";
 | 
			
		||||
import "./mixins/MixinKyberDmm.sol";
 | 
			
		||||
import "./mixins/MixinAaveV2.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
import "./mixins/MixinPlatypus.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV2.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract AvalancheBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(43114, "Avalanche"),
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
    MixinCurveV2,
 | 
			
		||||
    MixinGMX,
 | 
			
		||||
    MixinKyberDmm,
 | 
			
		||||
    MixinAaveV2,
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinPlatypus,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.CURVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.CURVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.KYBERDMM) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeKyberDmm(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.AAVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeAaveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.GMX) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeGMX(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.PLATYPUS) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradePlatypus(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }            
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        emit BridgeFill(
 | 
			
		||||
            order.source,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            boughtAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,132 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
import "./mixins/MixinDodo.sol";
 | 
			
		||||
import "./mixins/MixinDodoV2.sol";
 | 
			
		||||
import "./mixins/MixinKyberDmm.sol";
 | 
			
		||||
import "./mixins/MixinMooniswap.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV2.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract BSCBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(56, "BSC"),
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
    MixinDodo,
 | 
			
		||||
    MixinDodoV2,
 | 
			
		||||
    MixinKyberDmm,
 | 
			
		||||
    MixinMooniswap,
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
        MixinMooniswap(weth)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.CURVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.MOONISWAP) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeMooniswap(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.DODO) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeDodo(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.DODOV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeDodoV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.KYBERDMM) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeKyberDmm(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        emit BridgeFill(
 | 
			
		||||
            order.source,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            boughtAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -27,29 +27,34 @@ library BridgeProtocols {
 | 
			
		||||
    // A incrementally increasing, append-only list of protocol IDs.
 | 
			
		||||
    // We don't use an enum so solidity doesn't throw when we pass in a
 | 
			
		||||
    // new protocol ID that hasn't been rolled up yet.
 | 
			
		||||
    uint128 internal constant UNKNOWN     = 0;
 | 
			
		||||
    uint128 internal constant CURVE       = 1;
 | 
			
		||||
    uint128 internal constant UNISWAPV2   = 2;
 | 
			
		||||
    uint128 internal constant UNISWAP     = 3;
 | 
			
		||||
    uint128 internal constant BALANCER    = 4;
 | 
			
		||||
    uint128 internal constant KYBER       = 5;
 | 
			
		||||
    uint128 internal constant MOONISWAP   = 6;
 | 
			
		||||
    uint128 internal constant MSTABLE     = 7;
 | 
			
		||||
    uint128 internal constant OASIS       = 8;
 | 
			
		||||
    uint128 internal constant SHELL       = 9;
 | 
			
		||||
    uint128 internal constant DODO        = 10;
 | 
			
		||||
    uint128 internal constant DODOV2      = 11;
 | 
			
		||||
    uint128 internal constant CRYPTOCOM   = 12;
 | 
			
		||||
    uint128 internal constant BANCOR      = 13;
 | 
			
		||||
    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;
 | 
			
		||||
    uint128 internal constant KYBERDMM    = 19;
 | 
			
		||||
    uint128 internal constant CURVEV2     = 20;
 | 
			
		||||
    uint128 internal constant LIDO        = 21;
 | 
			
		||||
    uint128 internal constant CLIPPER     = 22; // Not used: Clipper is now using PLP interface
 | 
			
		||||
    uint128 internal constant AAVEV2      = 23;
 | 
			
		||||
    uint128 internal constant COMPOUND    = 24;
 | 
			
		||||
    uint128 internal constant UNKNOWN         = 0;
 | 
			
		||||
    uint128 internal constant CURVE           = 1;
 | 
			
		||||
    uint128 internal constant UNISWAPV2       = 2;
 | 
			
		||||
    uint128 internal constant UNISWAP         = 3;
 | 
			
		||||
    uint128 internal constant BALANCER        = 4;
 | 
			
		||||
    uint128 internal constant KYBER           = 5;  // Not used: deprecated.
 | 
			
		||||
    uint128 internal constant MOONISWAP       = 6;
 | 
			
		||||
    uint128 internal constant MSTABLE         = 7;
 | 
			
		||||
    uint128 internal constant OASIS           = 8;  // Not used: deprecated.
 | 
			
		||||
    uint128 internal constant SHELL           = 9;
 | 
			
		||||
    uint128 internal constant DODO            = 10;
 | 
			
		||||
    uint128 internal constant DODOV2          = 11;
 | 
			
		||||
    uint128 internal constant CRYPTOCOM       = 12;
 | 
			
		||||
    uint128 internal constant BANCOR          = 13;
 | 
			
		||||
    uint128 internal constant COFIX           = 14; // Not used: deprecated.
 | 
			
		||||
    uint128 internal constant NERVE           = 15;
 | 
			
		||||
    uint128 internal constant MAKERPSM        = 16;
 | 
			
		||||
    uint128 internal constant BALANCERV2      = 17;
 | 
			
		||||
    uint128 internal constant UNISWAPV3       = 18;
 | 
			
		||||
    uint128 internal constant KYBERDMM        = 19;
 | 
			
		||||
    uint128 internal constant CURVEV2         = 20;
 | 
			
		||||
    uint128 internal constant LIDO            = 21;
 | 
			
		||||
    uint128 internal constant CLIPPER         = 22; // Not used: Clipper is now using PLP interface
 | 
			
		||||
    uint128 internal constant AAVEV2          = 23;
 | 
			
		||||
    uint128 internal constant COMPOUND        = 24;
 | 
			
		||||
    uint128 internal constant BALANCERV2BATCH = 25;
 | 
			
		||||
    uint128 internal constant GMX             = 26;
 | 
			
		||||
    uint128 internal constant PLATYPUS        = 27;
 | 
			
		||||
    uint128 internal constant BANCORV3        = 28;
 | 
			
		||||
    uint128 internal constant VELODROME       = 29;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV2.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract CeloBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(42220, "Celo"),
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(address _weth)
 | 
			
		||||
        public
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }            
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        emit BridgeFill(
 | 
			
		||||
            order.source,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            boughtAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2021 ZeroEx Intl.
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
@@ -20,54 +20,52 @@
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./IBridgeAdapter.sol";
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinAaveV2.sol";
 | 
			
		||||
import "./mixins/MixinBalancer.sol";
 | 
			
		||||
import "./mixins/MixinBalancerV2.sol";
 | 
			
		||||
import "./mixins/MixinBalancerV2Batch.sol";
 | 
			
		||||
import "./mixins/MixinBancor.sol";
 | 
			
		||||
import "./mixins/MixinCoFiX.sol";
 | 
			
		||||
import "./mixins/MixinBancorV3.sol";
 | 
			
		||||
import "./mixins/MixinCompound.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
import "./mixins/MixinCurveV2.sol";
 | 
			
		||||
import "./mixins/MixinCryptoCom.sol";
 | 
			
		||||
import "./mixins/MixinDodo.sol";
 | 
			
		||||
import "./mixins/MixinDodoV2.sol";
 | 
			
		||||
import "./mixins/MixinKyber.sol";
 | 
			
		||||
import "./mixins/MixinKyberDmm.sol";
 | 
			
		||||
import "./mixins/MixinLido.sol";
 | 
			
		||||
import "./mixins/MixinMakerPSM.sol";
 | 
			
		||||
import "./mixins/MixinMooniswap.sol";
 | 
			
		||||
import "./mixins/MixinMStable.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
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,
 | 
			
		||||
contract EthereumBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(1, "Ethereum"),
 | 
			
		||||
    MixinAaveV2,
 | 
			
		||||
    MixinBalancer,
 | 
			
		||||
    MixinBalancerV2,
 | 
			
		||||
    MixinBalancerV2Batch,
 | 
			
		||||
    MixinBancor,
 | 
			
		||||
    MixinCoFiX,
 | 
			
		||||
    MixinBancorV3,
 | 
			
		||||
    MixinCompound,
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
    MixinCurveV2,
 | 
			
		||||
    MixinCryptoCom,
 | 
			
		||||
    MixinDodo,
 | 
			
		||||
    MixinDodoV2,
 | 
			
		||||
    MixinKyber,
 | 
			
		||||
    MixinKyberDmm,
 | 
			
		||||
    MixinLido,
 | 
			
		||||
    MixinMakerPSM,
 | 
			
		||||
    MixinMooniswap,
 | 
			
		||||
    MixinMStable,
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinOasis,
 | 
			
		||||
    MixinShell,
 | 
			
		||||
    MixinUniswap,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
@@ -76,43 +74,29 @@ contract BridgeAdapter is
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinAaveV2()
 | 
			
		||||
        MixinBalancer()
 | 
			
		||||
        MixinBalancerV2()
 | 
			
		||||
        MixinBancor(weth)
 | 
			
		||||
        MixinCoFiX()
 | 
			
		||||
        MixinBancorV3(weth)
 | 
			
		||||
        MixinCompound(weth)
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
        MixinCurveV2()
 | 
			
		||||
        MixinCryptoCom()
 | 
			
		||||
        MixinDodo()
 | 
			
		||||
        MixinDodoV2()
 | 
			
		||||
        MixinKyber(weth)
 | 
			
		||||
        MixinLido(weth)
 | 
			
		||||
        MixinMakerPSM()
 | 
			
		||||
        MixinMooniswap(weth)
 | 
			
		||||
        MixinMStable()
 | 
			
		||||
        MixinNerve()
 | 
			
		||||
        MixinOasis()
 | 
			
		||||
        MixinShell()
 | 
			
		||||
        MixinUniswap(weth)
 | 
			
		||||
        MixinUniswapV2()
 | 
			
		||||
        MixinUniswapV3()
 | 
			
		||||
        MixinZeroExBridge()
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function trade(
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.CURVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -120,6 +104,7 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.CURVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -127,18 +112,21 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV3) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV3(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAP) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswap(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -146,6 +134,7 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCER) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBalancer(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -153,20 +142,21 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCERV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBalancerV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.KYBER) {
 | 
			
		||||
            boughtAmount = _tradeKyber(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCERV2BATCH) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBalancerV2Batch(
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.MAKERPSM) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeMakerPsm(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -174,6 +164,7 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.MOONISWAP) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeMooniswap(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -181,20 +172,15 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.MSTABLE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeMStable(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.OASIS) {
 | 
			
		||||
            boughtAmount = _tradeOasis(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.SHELL) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeShell(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -202,49 +188,49 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.DODO) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeDodo(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.DODOV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeDodoV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.CRYPTOCOM) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCryptoCom(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BANCOR) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBancor(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.COFIX) {
 | 
			
		||||
            boughtAmount = _tradeCoFiX(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.KYBERDMM) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeKyberDmm(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.LIDO) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeLido(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -252,6 +238,7 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.AAVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeAaveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -259,13 +246,22 @@ contract BridgeAdapter is
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.COMPOUND) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCompound(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BANCORV3) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBancorV3(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
@@ -0,0 +1,124 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinAaveV2.sol";
 | 
			
		||||
import "./mixins/MixinBalancerV2.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
import "./mixins/MixinCurveV2.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV2.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract FantomBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(250, "Fantom"),
 | 
			
		||||
    MixinAaveV2,
 | 
			
		||||
    MixinBalancerV2,
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
    MixinCurveV2,
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.CURVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.CURVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCERV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBalancerV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.AAVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeAaveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }            
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        emit BridgeFill(
 | 
			
		||||
            order.source,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            boughtAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -50,6 +50,10 @@ interface IBridgeAdapter {
 | 
			
		||||
        uint256 outputTokenAmount
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    function isSupportedSource(bytes32 source)
 | 
			
		||||
        external
 | 
			
		||||
        returns (bool isSupported);
 | 
			
		||||
 | 
			
		||||
    function trade(
 | 
			
		||||
        BridgeOrder calldata order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,114 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
import "./mixins/MixinCurveV2.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV3.sol";
 | 
			
		||||
import "./mixins/MixinVelodrome.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract OptimismBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(10, "Optimism"),
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
    MixinCurveV2,
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinUniswapV3,
 | 
			
		||||
    MixinVelodrome,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.CURVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.CURVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV3) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV3(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.VELODROME) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeVelodrome(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }            
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        emit BridgeFill(
 | 
			
		||||
            order.source,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            boughtAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,178 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./AbstractBridgeAdapter.sol";
 | 
			
		||||
import "./BridgeProtocols.sol";
 | 
			
		||||
import "./mixins/MixinAaveV2.sol";
 | 
			
		||||
import "./mixins/MixinBalancerV2.sol";
 | 
			
		||||
import "./mixins/MixinBalancerV2Batch.sol";
 | 
			
		||||
import "./mixins/MixinCurve.sol";
 | 
			
		||||
import "./mixins/MixinCurveV2.sol";
 | 
			
		||||
import "./mixins/MixinDodo.sol";
 | 
			
		||||
import "./mixins/MixinDodoV2.sol";
 | 
			
		||||
import "./mixins/MixinKyberDmm.sol";
 | 
			
		||||
import "./mixins/MixinMStable.sol";
 | 
			
		||||
import "./mixins/MixinNerve.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV2.sol";
 | 
			
		||||
import "./mixins/MixinUniswapV3.sol";
 | 
			
		||||
import "./mixins/MixinZeroExBridge.sol";
 | 
			
		||||
 | 
			
		||||
contract PolygonBridgeAdapter is
 | 
			
		||||
    AbstractBridgeAdapter(137, "Polygon"),
 | 
			
		||||
    MixinAaveV2,
 | 
			
		||||
    MixinBalancerV2,
 | 
			
		||||
    MixinBalancerV2Batch,
 | 
			
		||||
    MixinCurve,
 | 
			
		||||
    MixinCurveV2,
 | 
			
		||||
    MixinDodo,
 | 
			
		||||
    MixinDodoV2,
 | 
			
		||||
    MixinKyberDmm,
 | 
			
		||||
    MixinMStable,
 | 
			
		||||
    MixinNerve,
 | 
			
		||||
    MixinUniswapV2,
 | 
			
		||||
    MixinUniswapV3,
 | 
			
		||||
    MixinZeroExBridge
 | 
			
		||||
{
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
        MixinCurve(weth)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    function _trade(
 | 
			
		||||
        BridgeOrder memory order,
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bool dryRun
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        override
 | 
			
		||||
        returns (uint256 boughtAmount, bool supportedSource)
 | 
			
		||||
    {
 | 
			
		||||
        uint128 protocolId = uint128(uint256(order.source) >> 128);
 | 
			
		||||
        if (protocolId == BridgeProtocols.CURVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.CURVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeCurveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV3) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV3(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNISWAPV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeUniswapV2(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCERV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBalancerV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.BALANCERV2BATCH) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeBalancerV2Batch(
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.MSTABLE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeMStable(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.DODO) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeDodo(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.DODOV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeDodoV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.NERVE) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeNerve(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.KYBERDMM) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeKyberDmm(
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.AAVEV2) {
 | 
			
		||||
            if (dryRun) { return (0, true); }
 | 
			
		||||
            boughtAmount = _tradeAaveV2(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        } else if (protocolId == BridgeProtocols.UNKNOWN) {
 | 
			
		||||
            if (dryRun) { return (0, true); }            
 | 
			
		||||
            boughtAmount = _tradeZeroExBridge(
 | 
			
		||||
                sellToken,
 | 
			
		||||
                buyToken,
 | 
			
		||||
                sellAmount,
 | 
			
		||||
                order.bridgeData
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        emit BridgeFill(
 | 
			
		||||
            order.source,
 | 
			
		||||
            sellToken,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            boughtAmount
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,107 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IBalancerV2BatchSwapVault {
 | 
			
		||||
 | 
			
		||||
    enum SwapKind { GIVEN_IN, GIVEN_OUT }
 | 
			
		||||
 | 
			
		||||
    struct BatchSwapStep {
 | 
			
		||||
        bytes32 poolId;
 | 
			
		||||
        uint256 assetInIndex;
 | 
			
		||||
        uint256 assetOutIndex;
 | 
			
		||||
        uint256 amount;
 | 
			
		||||
        bytes userData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct FundManagement {
 | 
			
		||||
        address sender;
 | 
			
		||||
        bool fromInternalBalance;
 | 
			
		||||
        address payable recipient;
 | 
			
		||||
        bool toInternalBalance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function batchSwap(
 | 
			
		||||
        SwapKind kind,
 | 
			
		||||
        BatchSwapStep[] calldata swaps,
 | 
			
		||||
        IERC20TokenV06[] calldata assets,
 | 
			
		||||
        FundManagement calldata funds,
 | 
			
		||||
        int256[] calldata limits,
 | 
			
		||||
        uint256 deadline
 | 
			
		||||
    ) external returns (int256[] memory amounts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinBalancerV2Batch {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    struct BalancerV2BatchBridgeData {
 | 
			
		||||
        IBalancerV2BatchSwapVault vault;
 | 
			
		||||
        IBalancerV2BatchSwapVault.BatchSwapStep[] swapSteps;
 | 
			
		||||
        IERC20TokenV06[] assets;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _tradeBalancerV2Batch(
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        // Decode the bridge data.
 | 
			
		||||
        (
 | 
			
		||||
            IBalancerV2BatchSwapVault vault,
 | 
			
		||||
            IBalancerV2BatchSwapVault.BatchSwapStep[] memory swapSteps,
 | 
			
		||||
            address[] memory assets_
 | 
			
		||||
        ) = abi.decode(bridgeData, (IBalancerV2BatchSwapVault, IBalancerV2BatchSwapVault.BatchSwapStep[], address[]));
 | 
			
		||||
        IERC20TokenV06[] memory assets;
 | 
			
		||||
        assembly { assets := assets_ }
 | 
			
		||||
 | 
			
		||||
        // Grant an allowance to the exchange to spend `fromTokenAddress` token.
 | 
			
		||||
        assets[0].approveIfBelow(address(vault), sellAmount);
 | 
			
		||||
 | 
			
		||||
        swapSteps[0].amount = sellAmount;
 | 
			
		||||
        int256[] memory limits = new int256[](assets.length);
 | 
			
		||||
        for (uint256 i = 0; i < limits.length; ++i) {
 | 
			
		||||
            limits[i] = type(int256).max;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int256[] memory amounts = vault.batchSwap(
 | 
			
		||||
            IBalancerV2BatchSwapVault.SwapKind.GIVEN_IN,
 | 
			
		||||
            swapSteps,
 | 
			
		||||
            assets,
 | 
			
		||||
            IBalancerV2BatchSwapVault.FundManagement({
 | 
			
		||||
                sender: address(this),
 | 
			
		||||
                fromInternalBalance: false,
 | 
			
		||||
                recipient: payable(address(this)),
 | 
			
		||||
                toInternalBalance: false
 | 
			
		||||
            }),
 | 
			
		||||
            limits,
 | 
			
		||||
            block.timestamp + 1
 | 
			
		||||
        );
 | 
			
		||||
        require(amounts[amounts.length - 1] <= 0, 'Unexpected BalancerV2Batch output');
 | 
			
		||||
        return uint256(amounts[amounts.length - 1] * -1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,128 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    BancorV3
 | 
			
		||||
*/
 | 
			
		||||
interface IBancorV3 {
 | 
			
		||||
    /**
 | 
			
		||||
     * @dev performs a trade by providing the source amount and returns the target amount and the associated fee
 | 
			
		||||
     *
 | 
			
		||||
     * requirements:
 | 
			
		||||
     *
 | 
			
		||||
     * - the caller must be the network contract
 | 
			
		||||
     */
 | 
			
		||||
    function tradeBySourceAmount(
 | 
			
		||||
        address sourceToken,
 | 
			
		||||
        address targetToken,
 | 
			
		||||
        uint256 sourceAmount,
 | 
			
		||||
        uint256 minReturnAmount,
 | 
			
		||||
        uint256 deadline,
 | 
			
		||||
        address beneficiary
 | 
			
		||||
    ) external payable returns (uint256 amount);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinBancorV3 {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    IERC20TokenV06 constant public BANCORV3_ETH_ADDRESS =
 | 
			
		||||
        IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
 | 
			
		||||
    IEtherTokenV06 private immutable WETH;
 | 
			
		||||
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
    {
 | 
			
		||||
        WETH = weth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _tradeBancorV3(
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 amountOut)
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        IBancorV3 router;
 | 
			
		||||
        IERC20TokenV06[] memory path;
 | 
			
		||||
        address[] memory _path;
 | 
			
		||||
        uint256 payableAmount = 0;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            (router, _path) = abi.decode(bridgeData, (IBancorV3, address[]));
 | 
			
		||||
            // To get around `abi.decode()` not supporting interface array types.
 | 
			
		||||
            assembly { path := _path }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        require(path.length >= 2, "MixinBancorV3/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
 | 
			
		||||
        require(
 | 
			
		||||
            path[path.length - 1] == buyToken,
 | 
			
		||||
            "MixinBancorV3/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        //swap WETH->ETH as Bancor only deals in ETH
 | 
			
		||||
        if(_path[0] == address(WETH)) {
 | 
			
		||||
            //withdraw the sell amount of WETH for ETH
 | 
			
		||||
            WETH.withdraw(sellAmount);
 | 
			
		||||
            payableAmount = sellAmount;
 | 
			
		||||
            // set _path[0] to the ETH address if WETH is our buy token
 | 
			
		||||
            _path[0] = address(BANCORV3_ETH_ADDRESS);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Grant the BancorV3 router an allowance to sell the first token.
 | 
			
		||||
            path[0].approveIfBelow(address(router), sellAmount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if we are buying WETH we need to swap to ETH and deposit into WETH after the swap
 | 
			
		||||
        if(_path[1] == address(WETH)){
 | 
			
		||||
            _path[1] = address(BANCORV3_ETH_ADDRESS);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        uint256 amountOut = router.tradeBySourceAmount{value: payableAmount}(
 | 
			
		||||
            _path[0],
 | 
			
		||||
            _path[1],
 | 
			
		||||
             // Sell all tokens we hold.
 | 
			
		||||
            sellAmount,
 | 
			
		||||
             // Minimum buy amount.
 | 
			
		||||
            1,
 | 
			
		||||
            //deadline
 | 
			
		||||
            block.timestamp + 1,
 | 
			
		||||
            // address of the mixin
 | 
			
		||||
            address(this)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // if we want to return WETH deposit the ETH amount we sold
 | 
			
		||||
        if(buyToken == WETH){
 | 
			
		||||
            WETH.deposit{value: amountOut}();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return amountOut;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface ICoFiXRouter {
 | 
			
		||||
    // msg.value = fee
 | 
			
		||||
    function swapExactTokensForETH(
 | 
			
		||||
        address token,
 | 
			
		||||
        uint amountIn,
 | 
			
		||||
        uint amountOutMin,
 | 
			
		||||
        address to,
 | 
			
		||||
        address rewardTo,
 | 
			
		||||
        uint deadline
 | 
			
		||||
    ) external payable returns (uint _amountIn, uint _amountOut);
 | 
			
		||||
 | 
			
		||||
    // msg.value = amountIn + fee
 | 
			
		||||
    function swapExactETHForTokens(
 | 
			
		||||
        address token,
 | 
			
		||||
        uint amountIn,
 | 
			
		||||
        uint amountOutMin,
 | 
			
		||||
        address to,
 | 
			
		||||
        address rewardTo,
 | 
			
		||||
        uint deadline
 | 
			
		||||
    ) external payable returns (uint _amountIn, uint _amountOut);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ICoFiXPair {
 | 
			
		||||
 | 
			
		||||
    function swapWithExact(address outToken, address to)
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (
 | 
			
		||||
            uint amountIn,
 | 
			
		||||
            uint amountOut,
 | 
			
		||||
            uint oracleFeeChange,
 | 
			
		||||
            uint256[4] memory tradeInfo
 | 
			
		||||
        );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinCoFiX {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    function _tradeCoFiX(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (uint256 fee, ICoFiXPair pool) = abi.decode(bridgeData, (uint256, ICoFiXPair));
 | 
			
		||||
        // Transfer tokens into the pool
 | 
			
		||||
        LibERC20TokenV06.compatTransfer(
 | 
			
		||||
            sellToken,
 | 
			
		||||
            address(pool),
 | 
			
		||||
            sellAmount
 | 
			
		||||
        );
 | 
			
		||||
        // Call the swap exact with the tokens now in the pool
 | 
			
		||||
        // pay the NEST Oracle fee with ETH
 | 
			
		||||
        (/* In */, boughtAmount, , ) = pool.swapWithExact{value: fee}(
 | 
			
		||||
            address(buyToken),
 | 
			
		||||
            address(this)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,98 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
import "../IBridgeAdapter.sol";
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    UniswapV2
 | 
			
		||||
*/
 | 
			
		||||
interface IGmxRouter {
 | 
			
		||||
 | 
			
		||||
    // /// @dev Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path.
 | 
			
		||||
    // ///      The first element of path is the input token, the last is the output token, and any intermediate elements represent
 | 
			
		||||
    // ///      intermediate pairs to trade through (if, for example, a direct pair does not exist).
 | 
			
		||||
    // /// @param _path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity.
 | 
			
		||||
    // /// @param _amountIn The amount of input tokens to send.
 | 
			
		||||
    // /// @param _minOut The minimum amount of output tokens that must be received for the transaction not to revert.
 | 
			
		||||
    // /// @param _reciever Recipient of the output tokens.
 | 
			
		||||
    function swap(
 | 
			
		||||
       address[] calldata _path, uint256 _amountIn, uint256 _minOut, address _receiver
 | 
			
		||||
    ) external;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinGMX {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
    using LibSafeMathV06 for uint256;
 | 
			
		||||
 | 
			
		||||
    function _tradeGMX(
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        address _router;
 | 
			
		||||
        address reader;
 | 
			
		||||
        address vault;
 | 
			
		||||
        address[] memory _path;
 | 
			
		||||
        IGmxRouter router;
 | 
			
		||||
        IERC20TokenV06[] memory path;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            //decode the bridge data
 | 
			
		||||
            (_router, reader, vault, _path) = abi.decode(bridgeData, (address, address, address, address[]));
 | 
			
		||||
            // To get around `abi.decode()` not supporting interface array types.
 | 
			
		||||
            assembly { path := _path }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        require(path.length >= 2, "MixinGMX/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
 | 
			
		||||
        require(
 | 
			
		||||
            path[path.length - 1] == buyToken,
 | 
			
		||||
            "MixinGMX/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        //connect to the GMX router
 | 
			
		||||
        router = IGmxRouter(_router);
 | 
			
		||||
 | 
			
		||||
        // Grant the GMX router an allowance to sell the first token.
 | 
			
		||||
        path[0].approveIfBelow(address(router), sellAmount);
 | 
			
		||||
 | 
			
		||||
        //track the balance to know how much we bought
 | 
			
		||||
        uint256 beforeBalance = buyToken.balanceOf(address(this));
 | 
			
		||||
        router.swap(
 | 
			
		||||
            // Convert to `buyToken` along this path.
 | 
			
		||||
            _path,
 | 
			
		||||
             // Sell all tokens we hold.
 | 
			
		||||
            sellAmount,
 | 
			
		||||
             // Minimum buy amount.
 | 
			
		||||
            0,
 | 
			
		||||
            // Recipient is `this`.
 | 
			
		||||
            address(this)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        //calculate the difference in balance from preswap->postswap to find how many tokens out
 | 
			
		||||
        boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance);
 | 
			
		||||
 | 
			
		||||
        return boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,124 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
 | 
			
		||||
import "../IBridgeAdapter.sol";
 | 
			
		||||
 | 
			
		||||
interface IKyberNetworkProxy {
 | 
			
		||||
 | 
			
		||||
    /// @dev Sells `sellTokenAddress` tokens for `buyTokenAddress` tokens
 | 
			
		||||
    /// using a hint for the reserve.
 | 
			
		||||
    /// @param sellToken Token to sell.
 | 
			
		||||
    /// @param sellAmount Amount of tokens to sell.
 | 
			
		||||
    /// @param buyToken Token to buy.
 | 
			
		||||
    /// @param recipientAddress Address to send bought tokens to.
 | 
			
		||||
    /// @param maxBuyTokenAmount A limit on the amount of tokens to buy.
 | 
			
		||||
    /// @param minConversionRate The minimal conversion rate. If actual rate
 | 
			
		||||
    ///        is lower, trade is canceled.
 | 
			
		||||
    /// @param walletId The wallet ID to send part of the fees
 | 
			
		||||
    /// @param hint The hint for the selective inclusion (or exclusion) of reserves
 | 
			
		||||
    /// @return boughtAmount Amount of tokens bought.
 | 
			
		||||
    function tradeWithHint(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        address payable recipientAddress,
 | 
			
		||||
        uint256 maxBuyTokenAmount,
 | 
			
		||||
        uint256 minConversionRate,
 | 
			
		||||
        address payable walletId,
 | 
			
		||||
        bytes calldata hint
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (uint256 boughtAmount);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinKyber {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    /// @dev Address indicating the trade is using ETH
 | 
			
		||||
    IERC20TokenV06 private immutable KYBER_ETH_ADDRESS =
 | 
			
		||||
        IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
 | 
			
		||||
    /// @dev Mainnet address of the WETH contract.
 | 
			
		||||
    IEtherTokenV06 private immutable WETH;
 | 
			
		||||
 | 
			
		||||
    constructor(IEtherTokenV06 weth)
 | 
			
		||||
        public
 | 
			
		||||
    {
 | 
			
		||||
        WETH = weth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _tradeKyber(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (IKyberNetworkProxy kyber, bytes memory hint) =
 | 
			
		||||
            abi.decode(bridgeData, (IKyberNetworkProxy, bytes));
 | 
			
		||||
 | 
			
		||||
        uint256 payableAmount = 0;
 | 
			
		||||
        if (sellToken != WETH) {
 | 
			
		||||
            // If the input token is not WETH, grant an allowance to the exchange
 | 
			
		||||
            // to spend them.
 | 
			
		||||
            sellToken.approveIfBelow(
 | 
			
		||||
                address(kyber),
 | 
			
		||||
                sellAmount
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            // If the input token is WETH, unwrap it and attach it to the call.
 | 
			
		||||
            payableAmount = sellAmount;
 | 
			
		||||
            WETH.withdraw(payableAmount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Try to sell all of this contract's input token balance through
 | 
			
		||||
        // `KyberNetworkProxy.trade()`.
 | 
			
		||||
        boughtAmount = kyber.tradeWithHint{ value: payableAmount }(
 | 
			
		||||
            // Input token.
 | 
			
		||||
            sellToken == WETH ? KYBER_ETH_ADDRESS : sellToken,
 | 
			
		||||
            // Sell amount.
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            // Output token.
 | 
			
		||||
            buyToken == WETH ? KYBER_ETH_ADDRESS : buyToken,
 | 
			
		||||
            // Transfer to this contract
 | 
			
		||||
            address(uint160(address(this))),
 | 
			
		||||
            // Buy as much as possible.
 | 
			
		||||
            uint256(-1),
 | 
			
		||||
            // Lowest minimum conversion rate
 | 
			
		||||
            1,
 | 
			
		||||
            // No affiliate address.
 | 
			
		||||
            address(0),
 | 
			
		||||
            hint
 | 
			
		||||
        );
 | 
			
		||||
        // If receving ETH, wrap it to WETH.
 | 
			
		||||
        if (buyToken == WETH) {
 | 
			
		||||
            WETH.deposit{ value: boughtAmount }();
 | 
			
		||||
        }
 | 
			
		||||
        return boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,7 +26,7 @@ import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev Minimal interface for minting StETH
 | 
			
		||||
interface ILido {
 | 
			
		||||
interface IStETH {
 | 
			
		||||
    /// @dev Adds eth to the pool
 | 
			
		||||
    /// @param _referral optional address for referrals
 | 
			
		||||
    /// @return StETH Amount of shares generated
 | 
			
		||||
@@ -37,6 +37,33 @@ interface ILido {
 | 
			
		||||
    function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @dev Minimal interface for wrapping/unwrapping stETH.
 | 
			
		||||
interface IWstETH {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @notice Exchanges stETH to wstETH
 | 
			
		||||
     * @param _stETHAmount amount of stETH to wrap in exchange for wstETH
 | 
			
		||||
     * @dev Requirements:
 | 
			
		||||
     *  - `_stETHAmount` must be non-zero
 | 
			
		||||
     *  - msg.sender must approve at least `_stETHAmount` stETH to this
 | 
			
		||||
     *    contract.
 | 
			
		||||
     *  - msg.sender must have at least `_stETHAmount` of stETH.
 | 
			
		||||
     * User should first approve _stETHAmount to the WstETH contract
 | 
			
		||||
     * @return Amount of wstETH user receives after wrap
 | 
			
		||||
     */
 | 
			
		||||
    function wrap(uint256 _stETHAmount) external returns (uint256);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @notice Exchanges wstETH to stETH
 | 
			
		||||
     * @param _wstETHAmount amount of wstETH to uwrap in exchange for stETH
 | 
			
		||||
     * @dev Requirements:
 | 
			
		||||
     *  - `_wstETHAmount` must be non-zero
 | 
			
		||||
     *  - msg.sender must have at least `_wstETHAmount` wstETH.
 | 
			
		||||
     * @return Amount of stETH user receives after unwrap
 | 
			
		||||
     */
 | 
			
		||||
    function unwrap(uint256 _wstETHAmount) external returns (uint256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract MixinLido {
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
@@ -59,12 +86,43 @@ contract MixinLido {
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (ILido lido) = abi.decode(bridgeData, (ILido));
 | 
			
		||||
        if (address(sellToken) == address(WETH) && address(buyToken) == address(lido)) {
 | 
			
		||||
        if (address(sellToken) == address(WETH)) {
 | 
			
		||||
            return _tradeStETH(buyToken, sellAmount, bridgeData);
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        return _tradeWstETH(sellToken, buyToken, sellAmount, bridgeData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _tradeStETH(
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    ) private returns (uint256 boughtAmount) {
 | 
			
		||||
        (IStETH stETH) = abi.decode(bridgeData, (IStETH));
 | 
			
		||||
        if (address(buyToken) == address(stETH)) {
 | 
			
		||||
            WETH.withdraw(sellAmount);
 | 
			
		||||
            boughtAmount = lido.getPooledEthByShares(lido.submit{ value: sellAmount}(address(0)));
 | 
			
		||||
        } else {
 | 
			
		||||
            revert("MixinLido/UNSUPPORTED_TOKEN_PAIR");
 | 
			
		||||
            return stETH.getPooledEthByShares(stETH.submit{ value: sellAmount}(address(0)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        revert("MixinLido/UNSUPPORTED_TOKEN_PAIR");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _tradeWstETH(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
 | 
			
		||||
    ) private returns(uint256 boughtAmount){
 | 
			
		||||
        (IEtherTokenV06 stETH, IWstETH wstETH) = abi.decode(bridgeData, (IEtherTokenV06, IWstETH));
 | 
			
		||||
        if (address(sellToken) == address(stETH) && address(buyToken) == address(wstETH) ) {
 | 
			
		||||
            sellToken.approveIfBelow(address(wstETH), sellAmount);
 | 
			
		||||
            return wstETH.wrap(sellAmount);
 | 
			
		||||
        }
 | 
			
		||||
        if (address(sellToken) == address(wstETH) && address(buyToken) == address(stETH) ) {
 | 
			
		||||
            return wstETH.unwrap(sellAmount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        revert("MixinLido/UNSUPPORTED_TOKEN_PAIR");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,76 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "../IBridgeAdapter.sol";
 | 
			
		||||
 | 
			
		||||
interface IOasis {
 | 
			
		||||
 | 
			
		||||
    /// @dev Sell `sellAmount` of `sellToken` token and receive `buyToken` token.
 | 
			
		||||
    /// @param sellToken The token being sold.
 | 
			
		||||
    /// @param sellAmount The amount of `sellToken` token being sold.
 | 
			
		||||
    /// @param buyToken The token being bought.
 | 
			
		||||
    /// @param minBoughtAmount Minimum amount of `buyToken` token to buy.
 | 
			
		||||
    /// @return boughtAmount Amount of `buyToken` bought.
 | 
			
		||||
    function sellAllAmount(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 minBoughtAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        returns (uint256 boughtAmount);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinOasis {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    function _tradeOasis(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        (IOasis oasis) = abi.decode(bridgeData, (IOasis));
 | 
			
		||||
 | 
			
		||||
        // Grant an allowance to the exchange to spend `sellToken` token.
 | 
			
		||||
        sellToken.approveIfBelow(
 | 
			
		||||
            address(oasis),
 | 
			
		||||
            sellAmount
 | 
			
		||||
        );
 | 
			
		||||
        // Try to sell all of this contract's `sellToken` token balance.
 | 
			
		||||
        boughtAmount = oasis.sellAllAmount(
 | 
			
		||||
            sellToken,
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            buyToken,
 | 
			
		||||
            // min fill amount
 | 
			
		||||
            1
 | 
			
		||||
        );
 | 
			
		||||
        return boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,98 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IPlatypusRouter {
 | 
			
		||||
 | 
			
		||||
    function swapTokensForTokens(
 | 
			
		||||
        address[] calldata tokenPath,
 | 
			
		||||
        address[] calldata poolPath,
 | 
			
		||||
        uint256 fromAmount,
 | 
			
		||||
        uint256 minimumToAmount,
 | 
			
		||||
        address to,
 | 
			
		||||
        uint256 deadline
 | 
			
		||||
    ) external returns (uint256 amountOut, uint256 haircut);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinPlatypus {
 | 
			
		||||
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
    using LibSafeMathV06 for uint256;
 | 
			
		||||
 | 
			
		||||
    function _tradePlatypus(
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
        IPlatypusRouter router;
 | 
			
		||||
        address _router;
 | 
			
		||||
        address[] memory _pool;
 | 
			
		||||
        IERC20TokenV06[] memory path;
 | 
			
		||||
        address[] memory _path;
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            (_router, _pool, _path) = abi.decode(bridgeData, (address, address[], address[]));
 | 
			
		||||
 | 
			
		||||
            // To get around `abi.decode()` not supporting interface array types.
 | 
			
		||||
            assembly { path := _path }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //connect to the ptp router
 | 
			
		||||
        router = IPlatypusRouter(_router);
 | 
			
		||||
 | 
			
		||||
        require(path.length >= 2, "MixinPlatypus/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
 | 
			
		||||
        require(
 | 
			
		||||
            path[path.length - 1] == buyToken,
 | 
			
		||||
            "MixinPlatypus/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
 | 
			
		||||
        );
 | 
			
		||||
        // Grant the Platypus router an allowance to sell the first token.
 | 
			
		||||
        path[0].approveIfBelow(address(router), sellAmount);
 | 
			
		||||
 | 
			
		||||
        //keep track of the previous balance to confirm amount out
 | 
			
		||||
        uint256 beforeBalance = buyToken.balanceOf(address(this));
 | 
			
		||||
 | 
			
		||||
        router.swapTokensForTokens(
 | 
			
		||||
            // Convert to `buyToken` along this path.
 | 
			
		||||
            _path,
 | 
			
		||||
            // pool to swap on
 | 
			
		||||
            _pool,
 | 
			
		||||
             // Sell all tokens we hold.
 | 
			
		||||
            sellAmount,
 | 
			
		||||
             // Minimum buy amount.
 | 
			
		||||
            0,
 | 
			
		||||
            // Recipient is `this`.
 | 
			
		||||
            address(this),
 | 
			
		||||
 | 
			
		||||
            block.timestamp + 1
 | 
			
		||||
        );
 | 
			
		||||
        //calculate the buy amount from the tokens we recieved
 | 
			
		||||
        boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance);
 | 
			
		||||
        return boughtAmount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,64 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6.5;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
 | 
			
		||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
 | 
			
		||||
 | 
			
		||||
interface IVelodromeRouter {
 | 
			
		||||
    function swapExactTokensForTokensSimple(
 | 
			
		||||
        uint256 amountIn,
 | 
			
		||||
        uint256 amountOutMin,
 | 
			
		||||
        address tokenFrom,
 | 
			
		||||
        address tokenTo,
 | 
			
		||||
        bool stable,
 | 
			
		||||
        address to,
 | 
			
		||||
        uint256 deadline
 | 
			
		||||
    ) external returns (uint256[] memory amounts); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract MixinVelodrome {
 | 
			
		||||
    using LibERC20TokenV06 for IERC20TokenV06;
 | 
			
		||||
 | 
			
		||||
    function _tradeVelodrome(
 | 
			
		||||
        IERC20TokenV06 sellToken,
 | 
			
		||||
        IERC20TokenV06 buyToken,
 | 
			
		||||
        uint256 sellAmount,
 | 
			
		||||
        bytes memory bridgeData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        returns (uint256 boughtAmount)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        (IVelodromeRouter router, bool stable) = abi.decode(bridgeData, (IVelodromeRouter, bool));
 | 
			
		||||
        sellToken.approveIfBelow(address(router), sellAmount);
 | 
			
		||||
 | 
			
		||||
        boughtAmount = router.swapExactTokensForTokensSimple(
 | 
			
		||||
            sellAmount,
 | 
			
		||||
            0, 
 | 
			
		||||
            address(sellToken),
 | 
			
		||||
            address(buyToken),
 | 
			
		||||
            stable,
 | 
			
		||||
            address(this),
 | 
			
		||||
            block.timestamp + 1
 | 
			
		||||
        )[1];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/contracts-zero-ex",
 | 
			
		||||
    "version": "0.31.1",
 | 
			
		||||
    "version": "0.35.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -41,9 +41,9 @@
 | 
			
		||||
        "rollback": "node ./lib/scripts/rollback.js"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
 | 
			
		||||
        "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature,AvalancheBridgeAdapter,BSCBridgeAdapter,CeloBridgeAdapter,EthereumBridgeAdapter,FantomBridgeAdapter,OptimismBridgeAdapter,PolygonBridgeAdapter",
 | 
			
		||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinVelodrome|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OptimismBridgeAdapter|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PolygonBridgeAdapter|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
			
		||||
    },
 | 
			
		||||
    "repository": {
 | 
			
		||||
        "type": "git",
 | 
			
		||||
@@ -55,14 +55,14 @@
 | 
			
		||||
    },
 | 
			
		||||
    "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.7.2",
 | 
			
		||||
        "@0x/contract-addresses": "^6.12.0",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.27",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.43",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.18",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.11",
 | 
			
		||||
        "@0x/abi-gen": "^5.8.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.16.0",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.32",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.46",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.23",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.14",
 | 
			
		||||
        "@0x/order-utils": "^10.4.28",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.8",
 | 
			
		||||
        "@0x/sol-compiler": "^4.8.1",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@types/isomorphic-fetch": "^0.0.35",
 | 
			
		||||
@@ -79,17 +79,17 @@
 | 
			
		||||
        "truffle": "^5.0.32",
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "~0.16.11",
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
        "typescript": "4.6.3"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/base-contract": "^6.4.5",
 | 
			
		||||
        "@0x/protocol-utils": "^1.11.1",
 | 
			
		||||
        "@0x/subproviders": "^6.6.2",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.1",
 | 
			
		||||
        "@0x/utils": "^6.5.0",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.2",
 | 
			
		||||
        "ethereum-types": "^3.6.0",
 | 
			
		||||
        "@0x/base-contract": "^6.5.0",
 | 
			
		||||
        "@0x/protocol-utils": "^11.15.0",
 | 
			
		||||
        "@0x/subproviders": "^6.6.5",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@0x/typescript-typings": "^5.3.1",
 | 
			
		||||
        "@0x/utils": "^6.5.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.5",
 | 
			
		||||
        "ethereum-types": "^3.7.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10",
 | 
			
		||||
        "ethers": "~4.0.4"
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,13 @@
 | 
			
		||||
import { ContractArtifact } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
import * as AffiliateFeeTransformer from '../generated-artifacts/AffiliateFeeTransformer.json';
 | 
			
		||||
import * as AvalancheBridgeAdapter from '../generated-artifacts/AvalancheBridgeAdapter.json';
 | 
			
		||||
import * as BatchFillNativeOrdersFeature from '../generated-artifacts/BatchFillNativeOrdersFeature.json';
 | 
			
		||||
import * as BridgeAdapter from '../generated-artifacts/BridgeAdapter.json';
 | 
			
		||||
import * as BSCBridgeAdapter from '../generated-artifacts/BSCBridgeAdapter.json';
 | 
			
		||||
import * as CeloBridgeAdapter from '../generated-artifacts/CeloBridgeAdapter.json';
 | 
			
		||||
import * as CurveLiquidityProvider from '../generated-artifacts/CurveLiquidityProvider.json';
 | 
			
		||||
import * as EthereumBridgeAdapter from '../generated-artifacts/EthereumBridgeAdapter.json';
 | 
			
		||||
import * as FantomBridgeAdapter from '../generated-artifacts/FantomBridgeAdapter.json';
 | 
			
		||||
import * as FeeCollector from '../generated-artifacts/FeeCollector.json';
 | 
			
		||||
import * as FeeCollectorController from '../generated-artifacts/FeeCollectorController.json';
 | 
			
		||||
import * as FillQuoteTransformer from '../generated-artifacts/FillQuoteTransformer.json';
 | 
			
		||||
@@ -30,9 +34,11 @@ import * as LogMetadataTransformer from '../generated-artifacts/LogMetadataTrans
 | 
			
		||||
import * as MetaTransactionsFeature from '../generated-artifacts/MetaTransactionsFeature.json';
 | 
			
		||||
import * as MultiplexFeature from '../generated-artifacts/MultiplexFeature.json';
 | 
			
		||||
import * as NativeOrdersFeature from '../generated-artifacts/NativeOrdersFeature.json';
 | 
			
		||||
import * as OptimismBridgeAdapter from '../generated-artifacts/OptimismBridgeAdapter.json';
 | 
			
		||||
import * as OtcOrdersFeature from '../generated-artifacts/OtcOrdersFeature.json';
 | 
			
		||||
import * as OwnableFeature from '../generated-artifacts/OwnableFeature.json';
 | 
			
		||||
import * as PayTakerTransformer from '../generated-artifacts/PayTakerTransformer.json';
 | 
			
		||||
import * as PolygonBridgeAdapter from '../generated-artifacts/PolygonBridgeAdapter.json';
 | 
			
		||||
import * as PositiveSlippageFeeTransformer from '../generated-artifacts/PositiveSlippageFeeTransformer.json';
 | 
			
		||||
import * as SimpleFunctionRegistryFeature from '../generated-artifacts/SimpleFunctionRegistryFeature.json';
 | 
			
		||||
import * as TransformERC20Feature from '../generated-artifacts/TransformERC20Feature.json';
 | 
			
		||||
@@ -58,7 +64,6 @@ export const artifacts = {
 | 
			
		||||
    AffiliateFeeTransformer: AffiliateFeeTransformer as ContractArtifact,
 | 
			
		||||
    MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact,
 | 
			
		||||
    LogMetadataTransformer: LogMetadataTransformer as ContractArtifact,
 | 
			
		||||
    BridgeAdapter: BridgeAdapter as ContractArtifact,
 | 
			
		||||
    LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact,
 | 
			
		||||
    ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact,
 | 
			
		||||
    NativeOrdersFeature: NativeOrdersFeature as ContractArtifact,
 | 
			
		||||
@@ -72,4 +77,11 @@ export const artifacts = {
 | 
			
		||||
    IMultiplexFeature: IMultiplexFeature as ContractArtifact,
 | 
			
		||||
    OtcOrdersFeature: OtcOrdersFeature as ContractArtifact,
 | 
			
		||||
    IOtcOrdersFeature: IOtcOrdersFeature as ContractArtifact,
 | 
			
		||||
    AvalancheBridgeAdapter: AvalancheBridgeAdapter as ContractArtifact,
 | 
			
		||||
    BSCBridgeAdapter: BSCBridgeAdapter as ContractArtifact,
 | 
			
		||||
    CeloBridgeAdapter: CeloBridgeAdapter as ContractArtifact,
 | 
			
		||||
    EthereumBridgeAdapter: EthereumBridgeAdapter as ContractArtifact,
 | 
			
		||||
    FantomBridgeAdapter: FantomBridgeAdapter as ContractArtifact,
 | 
			
		||||
    OptimismBridgeAdapter: OptimismBridgeAdapter as ContractArtifact,
 | 
			
		||||
    PolygonBridgeAdapter: PolygonBridgeAdapter as ContractArtifact,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,11 @@ export * from './bloom_filter_utils';
 | 
			
		||||
export { GREEDY_TOKENS } from './constants';
 | 
			
		||||
export {
 | 
			
		||||
    AffiliateFeeTransformerContract,
 | 
			
		||||
    BridgeAdapterContract,
 | 
			
		||||
    AvalancheBridgeAdapterContract,
 | 
			
		||||
    BSCBridgeAdapterContract,
 | 
			
		||||
    CeloBridgeAdapterContract,
 | 
			
		||||
    EthereumBridgeAdapterContract,
 | 
			
		||||
    FantomBridgeAdapterContract,
 | 
			
		||||
    FillQuoteTransformerContract,
 | 
			
		||||
    IOwnableFeatureContract,
 | 
			
		||||
    IOwnableFeatureEvents,
 | 
			
		||||
@@ -45,7 +49,9 @@ export {
 | 
			
		||||
    IZeroExContract,
 | 
			
		||||
    LogMetadataTransformerContract,
 | 
			
		||||
    MultiplexFeatureContract,
 | 
			
		||||
    OptimismBridgeAdapterContract,
 | 
			
		||||
    PayTakerTransformerContract,
 | 
			
		||||
    PolygonBridgeAdapterContract,
 | 
			
		||||
    PositiveSlippageFeeTransformerContract,
 | 
			
		||||
    TransformERC20FeatureContract,
 | 
			
		||||
    WethTransformerContract,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,13 @@
 | 
			
		||||
 * -----------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
export * from '../generated-wrappers/affiliate_fee_transformer';
 | 
			
		||||
export * from '../generated-wrappers/avalanche_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/b_s_c_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/batch_fill_native_orders_feature';
 | 
			
		||||
export * from '../generated-wrappers/bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/celo_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/curve_liquidity_provider';
 | 
			
		||||
export * from '../generated-wrappers/ethereum_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/fantom_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/fee_collector';
 | 
			
		||||
export * from '../generated-wrappers/fee_collector_controller';
 | 
			
		||||
export * from '../generated-wrappers/fill_quote_transformer';
 | 
			
		||||
@@ -28,9 +32,11 @@ export * from '../generated-wrappers/log_metadata_transformer';
 | 
			
		||||
export * from '../generated-wrappers/meta_transactions_feature';
 | 
			
		||||
export * from '../generated-wrappers/multiplex_feature';
 | 
			
		||||
export * from '../generated-wrappers/native_orders_feature';
 | 
			
		||||
export * from '../generated-wrappers/optimism_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/otc_orders_feature';
 | 
			
		||||
export * from '../generated-wrappers/ownable_feature';
 | 
			
		||||
export * from '../generated-wrappers/pay_taker_transformer';
 | 
			
		||||
export * from '../generated-wrappers/polygon_bridge_adapter';
 | 
			
		||||
export * from '../generated-wrappers/positive_slippage_fee_transformer';
 | 
			
		||||
export * from '../generated-wrappers/simple_function_registry_feature';
 | 
			
		||||
export * from '../generated-wrappers/transform_erc20_feature';
 | 
			
		||||
 
 | 
			
		||||
@@ -5,15 +5,20 @@
 | 
			
		||||
 */
 | 
			
		||||
import { ContractArtifact } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
import * as AbstractBridgeAdapter from '../test/generated-artifacts/AbstractBridgeAdapter.json';
 | 
			
		||||
import * as AffiliateFeeTransformer from '../test/generated-artifacts/AffiliateFeeTransformer.json';
 | 
			
		||||
import * as AvalancheBridgeAdapter from '../test/generated-artifacts/AvalancheBridgeAdapter.json';
 | 
			
		||||
import * as BatchFillNativeOrdersFeature from '../test/generated-artifacts/BatchFillNativeOrdersFeature.json';
 | 
			
		||||
import * as BootstrapFeature from '../test/generated-artifacts/BootstrapFeature.json';
 | 
			
		||||
import * as BridgeAdapter from '../test/generated-artifacts/BridgeAdapter.json';
 | 
			
		||||
import * as BridgeProtocols from '../test/generated-artifacts/BridgeProtocols.json';
 | 
			
		||||
import * as BSCBridgeAdapter from '../test/generated-artifacts/BSCBridgeAdapter.json';
 | 
			
		||||
import * as CeloBridgeAdapter from '../test/generated-artifacts/CeloBridgeAdapter.json';
 | 
			
		||||
import * as CurveLiquidityProvider from '../test/generated-artifacts/CurveLiquidityProvider.json';
 | 
			
		||||
import * as ERC1155OrdersFeature from '../test/generated-artifacts/ERC1155OrdersFeature.json';
 | 
			
		||||
import * as ERC165Feature from '../test/generated-artifacts/ERC165Feature.json';
 | 
			
		||||
import * as ERC721OrdersFeature from '../test/generated-artifacts/ERC721OrdersFeature.json';
 | 
			
		||||
import * as EthereumBridgeAdapter from '../test/generated-artifacts/EthereumBridgeAdapter.json';
 | 
			
		||||
import * as FantomBridgeAdapter from '../test/generated-artifacts/FantomBridgeAdapter.json';
 | 
			
		||||
import * as FeeCollector from '../test/generated-artifacts/FeeCollector.json';
 | 
			
		||||
import * as FeeCollectorController from '../test/generated-artifacts/FeeCollectorController.json';
 | 
			
		||||
import * as FillQuoteTransformer from '../test/generated-artifacts/FillQuoteTransformer.json';
 | 
			
		||||
@@ -101,26 +106,28 @@ import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransa
 | 
			
		||||
import * as MixinAaveV2 from '../test/generated-artifacts/MixinAaveV2.json';
 | 
			
		||||
import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
 | 
			
		||||
import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json';
 | 
			
		||||
import * as MixinBalancerV2Batch from '../test/generated-artifacts/MixinBalancerV2Batch.json';
 | 
			
		||||
import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
 | 
			
		||||
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
 | 
			
		||||
import * as MixinBancorV3 from '../test/generated-artifacts/MixinBancorV3.json';
 | 
			
		||||
import * as MixinCompound from '../test/generated-artifacts/MixinCompound.json';
 | 
			
		||||
import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json';
 | 
			
		||||
import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
 | 
			
		||||
import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json';
 | 
			
		||||
import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json';
 | 
			
		||||
import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json';
 | 
			
		||||
import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json';
 | 
			
		||||
import * as MixinGMX from '../test/generated-artifacts/MixinGMX.json';
 | 
			
		||||
import * as MixinKyberDmm from '../test/generated-artifacts/MixinKyberDmm.json';
 | 
			
		||||
import * as MixinLido from '../test/generated-artifacts/MixinLido.json';
 | 
			
		||||
import * as MixinMakerPSM from '../test/generated-artifacts/MixinMakerPSM.json';
 | 
			
		||||
import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json';
 | 
			
		||||
import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json';
 | 
			
		||||
import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json';
 | 
			
		||||
import * as MixinOasis from '../test/generated-artifacts/MixinOasis.json';
 | 
			
		||||
import * as MixinPlatypus from '../test/generated-artifacts/MixinPlatypus.json';
 | 
			
		||||
import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
 | 
			
		||||
import * as 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 MixinVelodrome from '../test/generated-artifacts/MixinVelodrome.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';
 | 
			
		||||
@@ -136,11 +143,13 @@ import * as NativeOrdersInfo from '../test/generated-artifacts/NativeOrdersInfo.
 | 
			
		||||
import * as NativeOrdersProtocolFees from '../test/generated-artifacts/NativeOrdersProtocolFees.json';
 | 
			
		||||
import * as NativeOrdersSettlement from '../test/generated-artifacts/NativeOrdersSettlement.json';
 | 
			
		||||
import * as NFTOrders from '../test/generated-artifacts/NFTOrders.json';
 | 
			
		||||
import * as OptimismBridgeAdapter from '../test/generated-artifacts/OptimismBridgeAdapter.json';
 | 
			
		||||
import * as OtcOrdersFeature from '../test/generated-artifacts/OtcOrdersFeature.json';
 | 
			
		||||
import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json';
 | 
			
		||||
import * as PancakeSwapFeature from '../test/generated-artifacts/PancakeSwapFeature.json';
 | 
			
		||||
import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.json';
 | 
			
		||||
import * as PermissionlessTransformerDeployer from '../test/generated-artifacts/PermissionlessTransformerDeployer.json';
 | 
			
		||||
import * as PolygonBridgeAdapter from '../test/generated-artifacts/PolygonBridgeAdapter.json';
 | 
			
		||||
import * as PositiveSlippageFeeTransformer from '../test/generated-artifacts/PositiveSlippageFeeTransformer.json';
 | 
			
		||||
import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json';
 | 
			
		||||
import * as TestBridge from '../test/generated-artifacts/TestBridge.json';
 | 
			
		||||
@@ -307,32 +316,41 @@ export const artifacts = {
 | 
			
		||||
    PositiveSlippageFeeTransformer: PositiveSlippageFeeTransformer as ContractArtifact,
 | 
			
		||||
    Transformer: Transformer as ContractArtifact,
 | 
			
		||||
    WethTransformer: WethTransformer as ContractArtifact,
 | 
			
		||||
    BridgeAdapter: BridgeAdapter as ContractArtifact,
 | 
			
		||||
    AbstractBridgeAdapter: AbstractBridgeAdapter as ContractArtifact,
 | 
			
		||||
    AvalancheBridgeAdapter: AvalancheBridgeAdapter as ContractArtifact,
 | 
			
		||||
    BSCBridgeAdapter: BSCBridgeAdapter as ContractArtifact,
 | 
			
		||||
    BridgeProtocols: BridgeProtocols as ContractArtifact,
 | 
			
		||||
    CeloBridgeAdapter: CeloBridgeAdapter as ContractArtifact,
 | 
			
		||||
    EthereumBridgeAdapter: EthereumBridgeAdapter as ContractArtifact,
 | 
			
		||||
    FantomBridgeAdapter: FantomBridgeAdapter as ContractArtifact,
 | 
			
		||||
    IBridgeAdapter: IBridgeAdapter as ContractArtifact,
 | 
			
		||||
    OptimismBridgeAdapter: OptimismBridgeAdapter as ContractArtifact,
 | 
			
		||||
    PolygonBridgeAdapter: PolygonBridgeAdapter as ContractArtifact,
 | 
			
		||||
    MixinAaveV2: MixinAaveV2 as ContractArtifact,
 | 
			
		||||
    MixinBalancer: MixinBalancer as ContractArtifact,
 | 
			
		||||
    MixinBalancerV2: MixinBalancerV2 as ContractArtifact,
 | 
			
		||||
    MixinBalancerV2Batch: MixinBalancerV2Batch as ContractArtifact,
 | 
			
		||||
    MixinBancor: MixinBancor as ContractArtifact,
 | 
			
		||||
    MixinCoFiX: MixinCoFiX as ContractArtifact,
 | 
			
		||||
    MixinBancorV3: MixinBancorV3 as ContractArtifact,
 | 
			
		||||
    MixinCompound: MixinCompound as ContractArtifact,
 | 
			
		||||
    MixinCryptoCom: MixinCryptoCom as ContractArtifact,
 | 
			
		||||
    MixinCurve: MixinCurve as ContractArtifact,
 | 
			
		||||
    MixinCurveV2: MixinCurveV2 as ContractArtifact,
 | 
			
		||||
    MixinDodo: MixinDodo as ContractArtifact,
 | 
			
		||||
    MixinDodoV2: MixinDodoV2 as ContractArtifact,
 | 
			
		||||
    MixinKyber: MixinKyber as ContractArtifact,
 | 
			
		||||
    MixinGMX: MixinGMX as ContractArtifact,
 | 
			
		||||
    MixinKyberDmm: MixinKyberDmm as ContractArtifact,
 | 
			
		||||
    MixinLido: MixinLido as ContractArtifact,
 | 
			
		||||
    MixinMStable: MixinMStable as ContractArtifact,
 | 
			
		||||
    MixinMakerPSM: MixinMakerPSM as ContractArtifact,
 | 
			
		||||
    MixinMooniswap: MixinMooniswap as ContractArtifact,
 | 
			
		||||
    MixinNerve: MixinNerve as ContractArtifact,
 | 
			
		||||
    MixinOasis: MixinOasis as ContractArtifact,
 | 
			
		||||
    MixinPlatypus: MixinPlatypus as ContractArtifact,
 | 
			
		||||
    MixinShell: MixinShell as ContractArtifact,
 | 
			
		||||
    MixinUniswap: MixinUniswap as ContractArtifact,
 | 
			
		||||
    MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
 | 
			
		||||
    MixinUniswapV3: MixinUniswapV3 as ContractArtifact,
 | 
			
		||||
    MixinVelodrome: MixinVelodrome as ContractArtifact,
 | 
			
		||||
    MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
 | 
			
		||||
    IERC1155Token: IERC1155Token as ContractArtifact,
 | 
			
		||||
    IERC721Token: IERC721Token as ContractArtifact,
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ import { artifacts } from '../artifacts';
 | 
			
		||||
import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge';
 | 
			
		||||
import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders';
 | 
			
		||||
import {
 | 
			
		||||
    BridgeAdapterContract,
 | 
			
		||||
    EthereumBridgeAdapterContract,
 | 
			
		||||
    FillQuoteTransformerContract,
 | 
			
		||||
    TestFillQuoteTransformerExchangeContract,
 | 
			
		||||
    TestFillQuoteTransformerHostContract,
 | 
			
		||||
@@ -52,7 +52,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
 | 
			
		||||
    let singleProtocolFee: BigNumber;
 | 
			
		||||
 | 
			
		||||
    const GAS_PRICE = 1337;
 | 
			
		||||
    const TEST_BRIDGE_SOURCE = hexUtils.random(32);
 | 
			
		||||
    // Left half is 0, corresponding to BridgeProtocol.Unknown
 | 
			
		||||
    const TEST_BRIDGE_SOURCE = hexUtils.leftPad(hexUtils.random(16), 32);
 | 
			
		||||
    const HIGH_BIT = new BigNumber(2).pow(255);
 | 
			
		||||
    const REVERT_AMOUNT = new BigNumber('0xdeadbeef');
 | 
			
		||||
 | 
			
		||||
@@ -64,8 +65,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            artifacts,
 | 
			
		||||
        );
 | 
			
		||||
        const bridgeAdapter = await BridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.BridgeAdapter,
 | 
			
		||||
        const bridgeAdapter = await EthereumBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.EthereumBridgeAdapter,
 | 
			
		||||
            env.provider,
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            artifacts,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,15 +3,20 @@
 | 
			
		||||
 * Warning: This file is auto-generated by contracts-gen. Don't edit manually.
 | 
			
		||||
 * -----------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
export * from '../test/generated-wrappers/abstract_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/affiliate_fee_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/avalanche_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/b_s_c_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/batch_fill_native_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/bootstrap_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/bridge_protocols';
 | 
			
		||||
export * from '../test/generated-wrappers/celo_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/curve_liquidity_provider';
 | 
			
		||||
export * from '../test/generated-wrappers/erc1155_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/erc165_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/erc721_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/ethereum_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/fantom_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/fee_collector';
 | 
			
		||||
export * from '../test/generated-wrappers/fee_collector_controller';
 | 
			
		||||
export * from '../test/generated-wrappers/fill_quote_transformer';
 | 
			
		||||
@@ -99,26 +104,28 @@ export * from '../test/generated-wrappers/meta_transactions_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_aave_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_balancer';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_balancer_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_balancer_v2_batch';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_bancor';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_co_fi_x';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_bancor_v3';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_compound';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_crypto_com';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_curve';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_curve_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_dodo';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_dodo_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_kyber';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_g_m_x';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_kyber_dmm';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_lido';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_m_stable';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_maker_p_s_m';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_mooniswap';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_nerve';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_oasis';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_platypus';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_shell';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_uniswap';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_uniswap_v2';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_uniswap_v3';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_velodrome';
 | 
			
		||||
export * from '../test/generated-wrappers/mixin_zero_ex_bridge';
 | 
			
		||||
export * from '../test/generated-wrappers/mooniswap_liquidity_provider';
 | 
			
		||||
export * from '../test/generated-wrappers/multiplex_feature';
 | 
			
		||||
@@ -134,11 +141,13 @@ export * from '../test/generated-wrappers/native_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/native_orders_info';
 | 
			
		||||
export * from '../test/generated-wrappers/native_orders_protocol_fees';
 | 
			
		||||
export * from '../test/generated-wrappers/native_orders_settlement';
 | 
			
		||||
export * from '../test/generated-wrappers/optimism_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/otc_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/ownable_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/pancake_swap_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/pay_taker_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/permissionless_transformer_deployer';
 | 
			
		||||
export * from '../test/generated-wrappers/polygon_bridge_adapter';
 | 
			
		||||
export * from '../test/generated-wrappers/positive_slippage_fee_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/simple_function_registry_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/test_bridge';
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,13 @@
 | 
			
		||||
    "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*", "./scripts/**/*"],
 | 
			
		||||
    "files": [
 | 
			
		||||
        "generated-artifacts/AffiliateFeeTransformer.json",
 | 
			
		||||
        "generated-artifacts/AvalancheBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/BSCBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/BatchFillNativeOrdersFeature.json",
 | 
			
		||||
        "generated-artifacts/BridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/CeloBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/CurveLiquidityProvider.json",
 | 
			
		||||
        "generated-artifacts/EthereumBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/FantomBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/FeeCollector.json",
 | 
			
		||||
        "generated-artifacts/FeeCollectorController.json",
 | 
			
		||||
        "generated-artifacts/FillQuoteTransformer.json",
 | 
			
		||||
@@ -28,23 +32,30 @@
 | 
			
		||||
        "generated-artifacts/MetaTransactionsFeature.json",
 | 
			
		||||
        "generated-artifacts/MultiplexFeature.json",
 | 
			
		||||
        "generated-artifacts/NativeOrdersFeature.json",
 | 
			
		||||
        "generated-artifacts/OptimismBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/OtcOrdersFeature.json",
 | 
			
		||||
        "generated-artifacts/OwnableFeature.json",
 | 
			
		||||
        "generated-artifacts/PayTakerTransformer.json",
 | 
			
		||||
        "generated-artifacts/PolygonBridgeAdapter.json",
 | 
			
		||||
        "generated-artifacts/PositiveSlippageFeeTransformer.json",
 | 
			
		||||
        "generated-artifacts/SimpleFunctionRegistryFeature.json",
 | 
			
		||||
        "generated-artifacts/TransformERC20Feature.json",
 | 
			
		||||
        "generated-artifacts/WethTransformer.json",
 | 
			
		||||
        "generated-artifacts/ZeroEx.json",
 | 
			
		||||
        "test/generated-artifacts/AbstractBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/AffiliateFeeTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/AvalancheBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/BSCBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/BatchFillNativeOrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/BootstrapFeature.json",
 | 
			
		||||
        "test/generated-artifacts/BridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/BridgeProtocols.json",
 | 
			
		||||
        "test/generated-artifacts/CeloBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/CurveLiquidityProvider.json",
 | 
			
		||||
        "test/generated-artifacts/ERC1155OrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/ERC165Feature.json",
 | 
			
		||||
        "test/generated-artifacts/ERC721OrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/EthereumBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/FantomBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/FeeCollector.json",
 | 
			
		||||
        "test/generated-artifacts/FeeCollectorController.json",
 | 
			
		||||
        "test/generated-artifacts/FillQuoteTransformer.json",
 | 
			
		||||
@@ -132,26 +143,28 @@
 | 
			
		||||
        "test/generated-artifacts/MixinAaveV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBalancer.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBalancerV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBalancerV2Batch.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBancor.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCoFiX.json",
 | 
			
		||||
        "test/generated-artifacts/MixinBancorV3.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCompound.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCryptoCom.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCurve.json",
 | 
			
		||||
        "test/generated-artifacts/MixinCurveV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinDodo.json",
 | 
			
		||||
        "test/generated-artifacts/MixinDodoV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinKyber.json",
 | 
			
		||||
        "test/generated-artifacts/MixinGMX.json",
 | 
			
		||||
        "test/generated-artifacts/MixinKyberDmm.json",
 | 
			
		||||
        "test/generated-artifacts/MixinLido.json",
 | 
			
		||||
        "test/generated-artifacts/MixinMStable.json",
 | 
			
		||||
        "test/generated-artifacts/MixinMakerPSM.json",
 | 
			
		||||
        "test/generated-artifacts/MixinMooniswap.json",
 | 
			
		||||
        "test/generated-artifacts/MixinNerve.json",
 | 
			
		||||
        "test/generated-artifacts/MixinOasis.json",
 | 
			
		||||
        "test/generated-artifacts/MixinPlatypus.json",
 | 
			
		||||
        "test/generated-artifacts/MixinShell.json",
 | 
			
		||||
        "test/generated-artifacts/MixinUniswap.json",
 | 
			
		||||
        "test/generated-artifacts/MixinUniswapV2.json",
 | 
			
		||||
        "test/generated-artifacts/MixinUniswapV3.json",
 | 
			
		||||
        "test/generated-artifacts/MixinVelodrome.json",
 | 
			
		||||
        "test/generated-artifacts/MixinZeroExBridge.json",
 | 
			
		||||
        "test/generated-artifacts/MooniswapLiquidityProvider.json",
 | 
			
		||||
        "test/generated-artifacts/MultiplexFeature.json",
 | 
			
		||||
@@ -167,11 +180,13 @@
 | 
			
		||||
        "test/generated-artifacts/NativeOrdersInfo.json",
 | 
			
		||||
        "test/generated-artifacts/NativeOrdersProtocolFees.json",
 | 
			
		||||
        "test/generated-artifacts/NativeOrdersSettlement.json",
 | 
			
		||||
        "test/generated-artifacts/OptimismBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/OtcOrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/OwnableFeature.json",
 | 
			
		||||
        "test/generated-artifacts/PancakeSwapFeature.json",
 | 
			
		||||
        "test/generated-artifacts/PayTakerTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/PermissionlessTransformerDeployer.json",
 | 
			
		||||
        "test/generated-artifacts/PolygonBridgeAdapter.json",
 | 
			
		||||
        "test/generated-artifacts/PositiveSlippageFeeTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/SimpleFunctionRegistryFeature.json",
 | 
			
		||||
        "test/generated-artifacts/TestBridge.json",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								package.json
									
									
									
									
									
								
							@@ -52,16 +52,16 @@
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "contractsPackages": "@0x/contracts-erc20 @0x/contracts-test-utils @0x/contracts-utils @0x/contracts-zero-ex @0x/contracts-treasury",
 | 
			
		||||
        "nonContractPackages": "@0x/migrations @0x/contract-wrappers @0x/contract-addresses @0x/contract-artifacts @0x/contract-wrappers-test @0x/asset-swapper",
 | 
			
		||||
        "nonContractPackages": "@0x/contract-wrappers @0x/contract-addresses @0x/contract-artifacts @0x/contract-wrappers-test @0x/asset-swapper",
 | 
			
		||||
        "ignoreTestsForPackages": "",
 | 
			
		||||
        "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic",
 | 
			
		||||
        "packagesWithDocPages": "@0x/contract-wrappers @0x/migrations",
 | 
			
		||||
        "packagesWithDocPages": "@0x/contract-wrappers",
 | 
			
		||||
        "ignoreDependencyVersions": "@types/styled-components @types/node",
 | 
			
		||||
        "ignoreDependencyVersionsForPackage": "contract-wrappers"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/monorepo-scripts": "^3.2.1",
 | 
			
		||||
        "@0x-lerna-fork/lerna": "3.16.10",
 | 
			
		||||
        "@0x/monorepo-scripts": "^3.2.4",
 | 
			
		||||
        "@0xproject/npm-cli-login": "^0.0.11",
 | 
			
		||||
        "async-child-process": "^1.1.1",
 | 
			
		||||
        "coveralls": "^3.0.0",
 | 
			
		||||
@@ -71,10 +71,11 @@
 | 
			
		||||
        "npm-run-all": "^4.1.2",
 | 
			
		||||
        "prettier": "1.19.1",
 | 
			
		||||
        "source-map-support": "^0.5.6",
 | 
			
		||||
        "typescript": "4.2.2",
 | 
			
		||||
        "typescript": "4.6.3",
 | 
			
		||||
        "wsrun": "^5.2.4"
 | 
			
		||||
    },
 | 
			
		||||
    "resolutions": {
 | 
			
		||||
        "merkle-patricia-tree": "3.0.0"
 | 
			
		||||
        "merkle-patricia-tree": "3.0.0",
 | 
			
		||||
        "**/bignumber.js": "^9.0.2"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,225 @@
 | 
			
		||||
[
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.62.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add MDEX on BSC",
 | 
			
		||||
                "pr": 496
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add KnightSwap on BSC",
 | 
			
		||||
                "pr": 498
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add Velodrome support on Optimism",
 | 
			
		||||
                "pr": 494
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Do not send empty entries on Quote Report",
 | 
			
		||||
                "pr": 501
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "KnightSwap/Mdex cosmetic change",
 | 
			
		||||
                "pr": 502
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Offboard JetSwap, CafeSwap, JulSwap, and PolyDex",
 | 
			
		||||
                "pr": 503
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1655244958
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.61.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add stETH wrap/unwrap support",
 | 
			
		||||
                "pr": 476
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Offboard/clean up Oasis, CoFix, and legacy Kyber",
 | 
			
		||||
                "pr": 482
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add MeshSwap on Polygon",
 | 
			
		||||
                "pr": 491
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1654284040
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.60.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Alias Balancer sor to the old version",
 | 
			
		||||
                "pr": 481
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1652931596
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.60.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add BiSwap on BSC",
 | 
			
		||||
                "pr": 467
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add GMX and Platypus on Avalanche and Enable KyberDMM on bsc",
 | 
			
		||||
                "pr": 478
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add Yoshi Exchange support in Fantom",
 | 
			
		||||
                "pr": 473
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix KyberDMM gas underestimation",
 | 
			
		||||
                "pr": 479
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1652919697
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.59.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Remove SnowSwap on mainnet",
 | 
			
		||||
                "pr": 468
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Offboard Swerve Finance and LinkSwap",
 | 
			
		||||
                "pr": 469
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Offboard Eth2Dai",
 | 
			
		||||
                "pr": 470
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add an optional IRfqClient for SwapQuoter#getSwapQuoteAsync",
 | 
			
		||||
                "pr": 467
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1652400434
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.58.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Update Saddle pools on Mainnet",
 | 
			
		||||
                "pr": 450
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.57.3",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix a runtime error related to BalancerV2SwapInfoCache",
 | 
			
		||||
                "pr": 472
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1652146864
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.57.2",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix missing AMM quotes on indicative Quote Reports",
 | 
			
		||||
                "pr": 466
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1651526551
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.57.1",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Added QUICK/ANY pair on Polygon",
 | 
			
		||||
                "pr": 464
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Added cvxFXS/FXS curve pool on mainnet",
 | 
			
		||||
                "pr": 465
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.57.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add BalancerV2 batch swap support",
 | 
			
		||||
                "pr": 462
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1650611093
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.56.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add estimatedGas to ExtendedQuoteReport",
 | 
			
		||||
                "pr": 463
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1650575781
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.55.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Fix fillRfqOrder VIP being used for swaps that need transformERC20",
 | 
			
		||||
                "pr": 461
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1649347667
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.54.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add true VIP support for eligible RFQt swaps",
 | 
			
		||||
                "pr": 458
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1649215576
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.53.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Adds support for STG/USDC pool on Curve Mainnet",
 | 
			
		||||
                "pr": 451
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Use neon-router in asset-swapper tests",
 | 
			
		||||
                "pr": 453
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add sampler blocknumber to quote report data",
 | 
			
		||||
                "pr": 448
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1648739346
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.52.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Adds support for mobius money on celo",
 | 
			
		||||
                "pr": 423
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.51.0",
 | 
			
		||||
        "changes": [
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Added `Curve` `YFI-ETH` pool",
 | 
			
		||||
                "pr": 444
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        "timestamp": 1646888282
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "version": "16.50.3",
 | 
			
		||||
        "changes": [
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,86 @@ Edit the package's CHANGELOG.json file only.
 | 
			
		||||
 | 
			
		||||
CHANGELOG
 | 
			
		||||
 | 
			
		||||
## v16.62.0 - _June 14, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add MDEX on BSC (#496)
 | 
			
		||||
    * Add KnightSwap on BSC (#498)
 | 
			
		||||
    * Add Velodrome support on Optimism (#494)
 | 
			
		||||
    * Do not send empty entries on Quote Report (#501)
 | 
			
		||||
    * KnightSwap/Mdex cosmetic change (#502)
 | 
			
		||||
    * Offboard JetSwap, CafeSwap, JulSwap, and PolyDex (#503)
 | 
			
		||||
 | 
			
		||||
## v16.61.0 - _June 3, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add stETH wrap/unwrap support (#476)
 | 
			
		||||
    * Offboard/clean up Oasis, CoFix, and legacy Kyber (#482)
 | 
			
		||||
    * Add MeshSwap on Polygon (#491)
 | 
			
		||||
 | 
			
		||||
## v16.60.1 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Alias Balancer sor to the old version (#481)
 | 
			
		||||
 | 
			
		||||
## v16.60.0 - _May 19, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add BiSwap on BSC (#467)
 | 
			
		||||
    * Add GMX and Platypus on Avalanche and Enable KyberDMM on bsc (#478)
 | 
			
		||||
    * Add Yoshi Exchange support in Fantom (#473)
 | 
			
		||||
    * Fix KyberDMM gas underestimation (#479)
 | 
			
		||||
 | 
			
		||||
## v16.59.0 - _May 13, 2022_
 | 
			
		||||
 | 
			
		||||
    * Remove SnowSwap on mainnet (#468)
 | 
			
		||||
    * Offboard Swerve Finance and LinkSwap (#469)
 | 
			
		||||
    * Offboard Eth2Dai (#470)
 | 
			
		||||
    * Add an optional IRfqClient for SwapQuoter#getSwapQuoteAsync (#467)
 | 
			
		||||
 | 
			
		||||
## v16.58.0 - _Invalid date_
 | 
			
		||||
 | 
			
		||||
    * Update Saddle pools on Mainnet (#450)
 | 
			
		||||
 | 
			
		||||
## v16.57.3 - _May 10, 2022_
 | 
			
		||||
 | 
			
		||||
    * Fix a runtime error related to BalancerV2SwapInfoCache (#472)
 | 
			
		||||
 | 
			
		||||
## v16.57.2 - _May 2, 2022_
 | 
			
		||||
 | 
			
		||||
    * Fix missing AMM quotes on indicative Quote Reports (#466)
 | 
			
		||||
 | 
			
		||||
## v16.57.1 - _Invalid date_
 | 
			
		||||
 | 
			
		||||
    * Added QUICK/ANY pair on Polygon (#464)
 | 
			
		||||
    * Added cvxFXS/FXS curve pool on mainnet (#465)
 | 
			
		||||
 | 
			
		||||
## v16.57.0 - _April 22, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add BalancerV2 batch swap support (#462)
 | 
			
		||||
 | 
			
		||||
## v16.56.0 - _April 21, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add estimatedGas to ExtendedQuoteReport (#463)
 | 
			
		||||
 | 
			
		||||
## v16.55.0 - _April 7, 2022_
 | 
			
		||||
 | 
			
		||||
    * Fix fillRfqOrder VIP being used for swaps that need transformERC20 (#461)
 | 
			
		||||
 | 
			
		||||
## v16.54.0 - _April 6, 2022_
 | 
			
		||||
 | 
			
		||||
    * Add true VIP support for eligible RFQt swaps (#458)
 | 
			
		||||
 | 
			
		||||
## v16.53.0 - _March 31, 2022_
 | 
			
		||||
 | 
			
		||||
    * Adds support for STG/USDC pool on Curve Mainnet (#451)
 | 
			
		||||
    * Use neon-router in asset-swapper tests (#453)
 | 
			
		||||
    * Add sampler blocknumber to quote report data (#448)
 | 
			
		||||
 | 
			
		||||
## v16.52.0 - _Invalid date_
 | 
			
		||||
 | 
			
		||||
    * Adds support for mobius money on celo (#423)
 | 
			
		||||
 | 
			
		||||
## v16.51.0 - _March 10, 2022_
 | 
			
		||||
 | 
			
		||||
    * Added `Curve` `YFI-ETH` pool (#444)
 | 
			
		||||
 | 
			
		||||
## v16.50.3 - _March 9, 2022_
 | 
			
		||||
 | 
			
		||||
    * Routing glue optimization (#439)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
    "shouldSaveStandardInput": true,
 | 
			
		||||
    "compilerSettings": {
 | 
			
		||||
        "evmVersion": "istanbul",
 | 
			
		||||
        "optimizer": { "enabled": true, "runs": 200, "details": { "yul": true, "deduplicate": true } },
 | 
			
		||||
        "optimizer": { "enabled": true, "runs": 200, "details": { "yul": false, "deduplicate": true } },
 | 
			
		||||
        "outputSelection": {
 | 
			
		||||
            "*": {
 | 
			
		||||
                "*": [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										105
									
								
								packages/asset-swapper/contracts/src/BalancerV2BatchSampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								packages/asset-swapper/contracts/src/BalancerV2BatchSampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
// 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 "./interfaces/IBalancerV2Vault.sol";
 | 
			
		||||
import "./BalancerV2Common.sol";
 | 
			
		||||
 | 
			
		||||
contract BalancerV2BatchSampler is BalancerV2Common {
 | 
			
		||||
 | 
			
		||||
    // Replaces amount for first step with each takerTokenAmount and calls queryBatchSwap using supplied steps
 | 
			
		||||
    /// @dev Sample sell quotes from Balancer V2 supporting multihops.
 | 
			
		||||
    /// @param swapSteps Array of swap steps (can be >= 1).
 | 
			
		||||
    /// @param swapAssets Array of token address for swaps.
 | 
			
		||||
    /// @param takerTokenAmounts Taker token sell amount for each sample.
 | 
			
		||||
    function sampleMultihopSellsFromBalancerV2(
 | 
			
		||||
        IBalancerV2Vault vault,
 | 
			
		||||
        IBalancerV2Vault.BatchSwapStep[] memory swapSteps,
 | 
			
		||||
        address[] memory swapAssets,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        IBalancerV2Vault.FundManagement memory swapFunds =
 | 
			
		||||
            _createSwapFunds();
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            swapSteps[0].amount = 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
 | 
			
		||||
                // Note - queryBatchSwap will return a delta for each token in the assets array and last asset should be tokenOut
 | 
			
		||||
                int256 amountOutFromPool = amounts[amounts.length - 1] * -1;
 | 
			
		||||
                if (amountOutFromPool <= 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                makerTokenAmounts[i] = uint256(amountOutFromPool);
 | 
			
		||||
            } catch {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Replaces amount for first step with each makerTokenAmount and calls queryBatchSwap using supplied steps
 | 
			
		||||
    /// @dev Sample buy quotes from Balancer V2 supporting multihops.
 | 
			
		||||
    /// @param swapSteps Array of swap steps (can be >= 1).
 | 
			
		||||
    /// @param swapAssets Array of token address for swaps.
 | 
			
		||||
    /// @param makerTokenAmounts Maker token buy amount for each sample.
 | 
			
		||||
    function sampleMultihopBuysFromBalancerV2(
 | 
			
		||||
        IBalancerV2Vault vault,
 | 
			
		||||
        IBalancerV2Vault.BatchSwapStep[] memory swapSteps,
 | 
			
		||||
        address[] memory swapAssets,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        returns (uint256[] memory takerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 numSamples = makerTokenAmounts.length;
 | 
			
		||||
        takerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        IBalancerV2Vault.FundManagement memory swapFunds =
 | 
			
		||||
            _createSwapFunds();
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            swapSteps[0].amount = makerTokenAmounts[i];
 | 
			
		||||
            try
 | 
			
		||||
                // Uses GIVEN_OUT type for Buy
 | 
			
		||||
                vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_OUT, swapSteps, swapAssets, swapFunds)
 | 
			
		||||
            // amounts represent pool balance deltas from the swap (incoming balance, outgoing balance)
 | 
			
		||||
            returns (int256[] memory amounts) {
 | 
			
		||||
                int256 amountIntoPool = amounts[0];
 | 
			
		||||
                if (amountIntoPool <= 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                takerTokenAmounts[i] = uint256(amountIntoPool);
 | 
			
		||||
            } catch {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								packages/asset-swapper/contracts/src/BalancerV2Common.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								packages/asset-swapper/contracts/src/BalancerV2Common.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
// 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 "./interfaces/IBalancerV2Vault.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract BalancerV2Common {
 | 
			
		||||
 | 
			
		||||
    function _createSwapFunds()
 | 
			
		||||
        internal
 | 
			
		||||
        view
 | 
			
		||||
        returns (IBalancerV2Vault.FundManagement memory)
 | 
			
		||||
    {
 | 
			
		||||
        return
 | 
			
		||||
            IBalancerV2Vault.FundManagement({
 | 
			
		||||
                sender: address(this),
 | 
			
		||||
                fromInternalBalance: false,
 | 
			
		||||
                recipient: payable(address(this)),
 | 
			
		||||
                toInternalBalance: false
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -21,44 +21,11 @@ pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./SamplerUtils.sol";
 | 
			
		||||
import "./interfaces/IBalancerV2Vault.sol";
 | 
			
		||||
import "./BalancerV2Common.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;
 | 
			
		||||
    }
 | 
			
		||||
contract BalancerV2Sampler is SamplerUtils, BalancerV2Common {
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from Balancer V2.
 | 
			
		||||
    /// @param poolInfo Struct with pool related data
 | 
			
		||||
@@ -68,7 +35,7 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
    /// @return makerTokenAmounts Maker amounts bought at each taker token
 | 
			
		||||
    ///         amount.
 | 
			
		||||
    function sampleSellsFromBalancerV2(
 | 
			
		||||
        BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
@@ -78,9 +45,9 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
        IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault);
 | 
			
		||||
        IAsset[] memory swapAssets = new IAsset[](2);
 | 
			
		||||
        swapAssets[0] = IAsset(takerToken);
 | 
			
		||||
        swapAssets[1] = IAsset(makerToken);
 | 
			
		||||
        address[] memory swapAssets = new address[](2);
 | 
			
		||||
        swapAssets[0] = takerToken;
 | 
			
		||||
        swapAssets[1] = makerToken;
 | 
			
		||||
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
@@ -97,7 +64,7 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
            // 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;
 | 
			
		||||
                int256 amountOutFromPool = amounts[amounts.length - 1] * -1;
 | 
			
		||||
                if (amountOutFromPool <= 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
@@ -117,7 +84,7 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
    /// @return takerTokenAmounts Taker amounts sold at each maker token
 | 
			
		||||
    ///         amount.
 | 
			
		||||
    function sampleBuysFromBalancerV2(
 | 
			
		||||
        BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
@@ -127,9 +94,9 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
        IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault);
 | 
			
		||||
        IAsset[] memory swapAssets = new IAsset[](2);
 | 
			
		||||
        swapAssets[0] = IAsset(takerToken);
 | 
			
		||||
        swapAssets[1] = IAsset(makerToken);
 | 
			
		||||
        address[] memory swapAssets = new address[](2);
 | 
			
		||||
        swapAssets[0] = takerToken;
 | 
			
		||||
        swapAssets[1] = makerToken;
 | 
			
		||||
 | 
			
		||||
        uint256 numSamples = makerTokenAmounts.length;
 | 
			
		||||
        takerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
@@ -157,7 +124,7 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _createSwapSteps(
 | 
			
		||||
        BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo,
 | 
			
		||||
        uint256 amount
 | 
			
		||||
    ) private pure returns (IBalancerV2Vault.BatchSwapStep[] memory) {
 | 
			
		||||
        IBalancerV2Vault.BatchSwapStep[] memory swapSteps =
 | 
			
		||||
@@ -172,18 +139,4 @@ contract BalancerV2Sampler is SamplerUtils {
 | 
			
		||||
 | 
			
		||||
        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,9 +22,8 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IBancor.sol";
 | 
			
		||||
 | 
			
		||||
contract CompilerHack {}
 | 
			
		||||
 | 
			
		||||
contract BancorSampler is CompilerHack {
 | 
			
		||||
contract BancorSampler {
 | 
			
		||||
 | 
			
		||||
    /// @dev Base gas limit for Bancor calls.
 | 
			
		||||
    uint256 constant private BANCOR_CALL_GAS = 300e3; // 300k
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										120
									
								
								packages/asset-swapper/contracts/src/BancorV3Sampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								packages/asset-swapper/contracts/src/BancorV3Sampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IBancorV3.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract BancorV3Sampler
 | 
			
		||||
{
 | 
			
		||||
    /// @dev Gas limit for BancorV3 calls.
 | 
			
		||||
    uint256 constant private BancorV3_CALL_GAS = 150e3; // 150k
 | 
			
		||||
 | 
			
		||||
    address constant public ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from BancorV3.
 | 
			
		||||
    /// @param weth The WETH contract address
 | 
			
		||||
    /// @param router Router to look up tokens and amounts
 | 
			
		||||
    /// @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.
 | 
			
		||||
    function sampleSellsFromBancorV3(
 | 
			
		||||
        address weth,
 | 
			
		||||
        address router,
 | 
			
		||||
        address[] memory path,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
 | 
			
		||||
        if(path[0] == weth){
 | 
			
		||||
            path[0] = ETH;
 | 
			
		||||
        }
 | 
			
		||||
        if(path[1] == weth){
 | 
			
		||||
            path[1] = ETH;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            try
 | 
			
		||||
                IBancorV3(router).tradeOutputBySourceAmount(path[0], path[1], takerTokenAmounts[i])
 | 
			
		||||
                returns (uint256 amount)
 | 
			
		||||
            {
 | 
			
		||||
                makerTokenAmounts[i] = amount;
 | 
			
		||||
                // Break early if there are 0 amounts
 | 
			
		||||
                if (makerTokenAmounts[i] == 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample buy quotes from BancorV3.
 | 
			
		||||
    /// @param weth The WETH contract address
 | 
			
		||||
    /// @param router Router to look up tokens and amounts
 | 
			
		||||
    /// @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.
 | 
			
		||||
    function sampleBuysFromBancorV3(
 | 
			
		||||
        address weth,
 | 
			
		||||
        address router,
 | 
			
		||||
        address[] memory path,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory takerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 numSamples = makerTokenAmounts.length;
 | 
			
		||||
        takerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
 | 
			
		||||
        if(path[0] == weth){
 | 
			
		||||
            path[0] = ETH;
 | 
			
		||||
        }
 | 
			
		||||
        if(path[1] == weth){
 | 
			
		||||
            path[1] = ETH;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            try
 | 
			
		||||
                IBancorV3(router).tradeInputByTargetAmount(path[0], path[1], makerTokenAmounts[i])
 | 
			
		||||
                returns (uint256 amount)
 | 
			
		||||
            {
 | 
			
		||||
                takerTokenAmounts[i] = amount;
 | 
			
		||||
                // Break early if there are 0 amounts
 | 
			
		||||
                if (takerTokenAmounts[i] == 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,52 +22,58 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./BalancerSampler.sol";
 | 
			
		||||
import "./BalancerV2Sampler.sol";
 | 
			
		||||
import "./BalancerV2BatchSampler.sol";
 | 
			
		||||
import "./BancorSampler.sol";
 | 
			
		||||
import "./BancorV3Sampler.sol";
 | 
			
		||||
import "./CompoundSampler.sol";
 | 
			
		||||
import "./CurveSampler.sol";
 | 
			
		||||
import "./DODOSampler.sol";
 | 
			
		||||
import "./DODOV2Sampler.sol";
 | 
			
		||||
import "./KyberSampler.sol";
 | 
			
		||||
import "./GMXSampler.sol";
 | 
			
		||||
import "./KyberDmmSampler.sol";
 | 
			
		||||
import "./LidoSampler.sol";
 | 
			
		||||
import "./LiquidityProviderSampler.sol";
 | 
			
		||||
import "./MakerPSMSampler.sol";
 | 
			
		||||
import "./MultiBridgeSampler.sol";
 | 
			
		||||
import "./MStableSampler.sol";
 | 
			
		||||
import "./MooniswapSampler.sol";
 | 
			
		||||
import "./NativeOrderSampler.sol";
 | 
			
		||||
import "./PlatypusSampler.sol";
 | 
			
		||||
import "./ShellSampler.sol";
 | 
			
		||||
import "./SmoothySampler.sol";
 | 
			
		||||
import "./TwoHopSampler.sol";
 | 
			
		||||
import "./UniswapSampler.sol";
 | 
			
		||||
import "./UniswapV2Sampler.sol";
 | 
			
		||||
import "./UniswapV3Sampler.sol";
 | 
			
		||||
import "./VelodromeSampler.sol";
 | 
			
		||||
import "./UtilitySampler.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract ERC20BridgeSampler is
 | 
			
		||||
    BalancerSampler,
 | 
			
		||||
    BalancerV2Sampler,
 | 
			
		||||
    BalancerV2BatchSampler,
 | 
			
		||||
    BancorSampler,
 | 
			
		||||
    BancorV3Sampler,
 | 
			
		||||
    CompoundSampler,
 | 
			
		||||
    CurveSampler,
 | 
			
		||||
    DODOSampler,
 | 
			
		||||
    DODOV2Sampler,
 | 
			
		||||
    KyberSampler,
 | 
			
		||||
    GMXSampler,
 | 
			
		||||
    KyberDmmSampler,
 | 
			
		||||
    LidoSampler,
 | 
			
		||||
    LiquidityProviderSampler,
 | 
			
		||||
    MakerPSMSampler,
 | 
			
		||||
    MStableSampler,
 | 
			
		||||
    MooniswapSampler,
 | 
			
		||||
    MultiBridgeSampler,
 | 
			
		||||
    NativeOrderSampler,
 | 
			
		||||
    PlatypusSampler,
 | 
			
		||||
    ShellSampler,
 | 
			
		||||
    SmoothySampler,
 | 
			
		||||
    TwoHopSampler,
 | 
			
		||||
    UniswapSampler,
 | 
			
		||||
    UniswapV2Sampler,
 | 
			
		||||
    UniswapV3Sampler,
 | 
			
		||||
    VelodromeSampler,
 | 
			
		||||
    UtilitySampler
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@@ -92,4 +98,6 @@ contract ERC20BridgeSampler is
 | 
			
		||||
            (callResults[i].success, callResults[i].data) = address(this).call(callDatas[i]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    receive() external payable {}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								packages/asset-swapper/contracts/src/GMXSampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								packages/asset-swapper/contracts/src/GMXSampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IGMX.sol";
 | 
			
		||||
import "./ApproximateBuys.sol";
 | 
			
		||||
import "./SamplerUtils.sol";
 | 
			
		||||
 | 
			
		||||
contract GMXSampler is
 | 
			
		||||
    SamplerUtils,
 | 
			
		||||
    ApproximateBuys
 | 
			
		||||
{
 | 
			
		||||
    struct GMXInfo {
 | 
			
		||||
        address reader;
 | 
			
		||||
        address vault;
 | 
			
		||||
        address[] path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function sampleSellsFromGMX(
 | 
			
		||||
        address reader,
 | 
			
		||||
        address vault,
 | 
			
		||||
        address[] memory path,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            try
 | 
			
		||||
                IGMX(reader).getAmountOut(IVault(vault), path[0], path[1], takerTokenAmounts[i])
 | 
			
		||||
                returns (uint256 amountAfterFees, uint256 feeAmount)
 | 
			
		||||
            {
 | 
			
		||||
                makerTokenAmounts[i] = amountAfterFees;
 | 
			
		||||
                // Break early if there are 0 amounts
 | 
			
		||||
                if (makerTokenAmounts[i] == 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function sampleBuysFromGMX(
 | 
			
		||||
        address reader,
 | 
			
		||||
        address vault,
 | 
			
		||||
        address[] memory path,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory takerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        address[] memory invertBuyPath = new address[](2);
 | 
			
		||||
        invertBuyPath[0] = path[1];
 | 
			
		||||
        invertBuyPath[1] = path[0];
 | 
			
		||||
        return _sampleApproximateBuys(
 | 
			
		||||
                ApproximateBuyQuoteOpts({
 | 
			
		||||
                    makerTokenData: abi.encode(reader, vault, invertBuyPath),
 | 
			
		||||
                    takerTokenData: abi.encode(reader, vault, path),
 | 
			
		||||
                    getSellQuoteCallback: _sampleSellForApproximateBuyFromGMX
 | 
			
		||||
                }),
 | 
			
		||||
                makerTokenAmounts
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function _sampleSellForApproximateBuyFromGMX(
 | 
			
		||||
        bytes memory takerTokenData,
 | 
			
		||||
        bytes memory makerTokenData,
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    )
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 buyAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (address _reader, address _vault, address[] memory _path ) = abi.decode(takerTokenData, (address, address, address[]));
 | 
			
		||||
 | 
			
		||||
        (bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector(
 | 
			
		||||
            this.sampleSellsFromGMX.selector,
 | 
			
		||||
            _reader,
 | 
			
		||||
            _vault,
 | 
			
		||||
            _path,
 | 
			
		||||
            _toSingleValueArray(sellAmount)
 | 
			
		||||
        ));
 | 
			
		||||
        if(!success) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        // solhint-disable-next-line indent
 | 
			
		||||
        return abi.decode(resultData, (uint256[]))[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,301 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IKyberNetwork.sol";
 | 
			
		||||
import "./ApproximateBuys.sol";
 | 
			
		||||
import "./SamplerUtils.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract KyberSampler is
 | 
			
		||||
    SamplerUtils,
 | 
			
		||||
    ApproximateBuys
 | 
			
		||||
{
 | 
			
		||||
    /// @dev Gas limit for Kyber calls.
 | 
			
		||||
    uint256 constant private KYBER_CALL_GAS = 500e3; // 500k
 | 
			
		||||
    /// @dev Kyber ETH pseudo-address.
 | 
			
		||||
    address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
 | 
			
		||||
 | 
			
		||||
    struct KyberSamplerOpts {
 | 
			
		||||
        uint256 reserveOffset;
 | 
			
		||||
        address hintHandler;
 | 
			
		||||
        address networkProxy;
 | 
			
		||||
        address weth;
 | 
			
		||||
        bytes hint;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from Kyber.
 | 
			
		||||
    /// @param opts KyberSamplerOpts The nth reserve
 | 
			
		||||
    /// @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 reserveId The id of the reserve found at reserveOffset
 | 
			
		||||
    /// @return hint The hint for the selected reserve
 | 
			
		||||
    /// @return makerTokenAmounts Maker amounts bought at each taker token amount.
 | 
			
		||||
    function sampleSellsFromKyberNetwork(
 | 
			
		||||
        KyberSamplerOpts memory opts,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes32 reserveId, bytes memory hint, uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
        reserveId = _getNextReserveId(opts, takerToken, makerToken);
 | 
			
		||||
        if (reserveId == 0x0) {
 | 
			
		||||
            return (reserveId, hint, makerTokenAmounts);
 | 
			
		||||
        }
 | 
			
		||||
        opts.hint = this.encodeKyberHint(opts, reserveId, takerToken, makerToken);
 | 
			
		||||
        hint = opts.hint;
 | 
			
		||||
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            uint256 value = this.sampleSellFromKyberNetwork(
 | 
			
		||||
                opts,
 | 
			
		||||
                takerToken,
 | 
			
		||||
                makerToken,
 | 
			
		||||
                takerTokenAmounts[i]
 | 
			
		||||
            );
 | 
			
		||||
            makerTokenAmounts[i] = value;
 | 
			
		||||
            // Break early if there are 0 amounts
 | 
			
		||||
            if (makerTokenAmounts[i] == 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample buy quotes from Kyber.
 | 
			
		||||
    /// @param opts KyberSamplerOpts The nth reserve
 | 
			
		||||
    /// @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 reserveId The id of the reserve found at reserveOffset
 | 
			
		||||
    /// @return hint The hint for the selected reserve
 | 
			
		||||
    /// @return takerTokenAmounts Taker amounts sold at each maker token amount.
 | 
			
		||||
    function sampleBuysFromKyberNetwork(
 | 
			
		||||
        KyberSamplerOpts memory opts,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes32 reserveId, bytes memory hint, uint256[] memory takerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
 | 
			
		||||
        reserveId = _getNextReserveId(opts, takerToken, makerToken);
 | 
			
		||||
        if (reserveId == 0x0) {
 | 
			
		||||
            return (reserveId, hint, takerTokenAmounts);
 | 
			
		||||
        }
 | 
			
		||||
        opts.hint = this.encodeKyberHint(opts, reserveId, takerToken, makerToken);
 | 
			
		||||
        hint = opts.hint;
 | 
			
		||||
 | 
			
		||||
        takerTokenAmounts = _sampleApproximateBuys(
 | 
			
		||||
            ApproximateBuyQuoteOpts({
 | 
			
		||||
                makerTokenData: abi.encode(makerToken, opts),
 | 
			
		||||
                takerTokenData: abi.encode(takerToken, opts),
 | 
			
		||||
                getSellQuoteCallback: _sampleSellForApproximateBuyFromKyber
 | 
			
		||||
            }),
 | 
			
		||||
            makerTokenAmounts
 | 
			
		||||
        );
 | 
			
		||||
        return (reserveId, hint, takerTokenAmounts);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function encodeKyberHint(
 | 
			
		||||
        KyberSamplerOpts memory opts,
 | 
			
		||||
        bytes32 reserveId,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes memory hint)
 | 
			
		||||
    {
 | 
			
		||||
        // Build a hint selecting the single reserve
 | 
			
		||||
        IKyberHintHandler kyberHint = IKyberHintHandler(opts.hintHandler);
 | 
			
		||||
 | 
			
		||||
        // All other reserves should be ignored with this hint
 | 
			
		||||
        bytes32[] memory selectedReserves = new bytes32[](1);
 | 
			
		||||
        selectedReserves[0] = reserveId;
 | 
			
		||||
        uint256[] memory emptySplits = new uint256[](0);
 | 
			
		||||
 | 
			
		||||
        if (takerToken == opts.weth) {
 | 
			
		||||
            // ETH to Token
 | 
			
		||||
            try
 | 
			
		||||
                kyberHint.buildEthToTokenHint
 | 
			
		||||
                    {gas: KYBER_CALL_GAS}
 | 
			
		||||
                    (
 | 
			
		||||
                        makerToken,
 | 
			
		||||
                        IKyberHintHandler.TradeType.MaskIn,
 | 
			
		||||
                        selectedReserves,
 | 
			
		||||
                        emptySplits
 | 
			
		||||
                    )
 | 
			
		||||
                returns (bytes memory result)
 | 
			
		||||
            {
 | 
			
		||||
                return result;
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
            }
 | 
			
		||||
        } else if (makerToken == opts.weth) {
 | 
			
		||||
            // Token to ETH
 | 
			
		||||
            try
 | 
			
		||||
                kyberHint.buildTokenToEthHint
 | 
			
		||||
                    {gas: KYBER_CALL_GAS}
 | 
			
		||||
                    (
 | 
			
		||||
                        takerToken,
 | 
			
		||||
                        IKyberHintHandler.TradeType.MaskIn,
 | 
			
		||||
                        selectedReserves,
 | 
			
		||||
                        emptySplits
 | 
			
		||||
                    )
 | 
			
		||||
                returns (bytes memory result)
 | 
			
		||||
            {
 | 
			
		||||
                return result;
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            // Token to Token
 | 
			
		||||
            // We use the same reserve both ways
 | 
			
		||||
            try
 | 
			
		||||
                kyberHint.buildTokenToTokenHint
 | 
			
		||||
                    {gas: KYBER_CALL_GAS}
 | 
			
		||||
                    (
 | 
			
		||||
                        takerToken,
 | 
			
		||||
                        IKyberHintHandler.TradeType.MaskIn,
 | 
			
		||||
                        selectedReserves,
 | 
			
		||||
                        emptySplits,
 | 
			
		||||
                        makerToken,
 | 
			
		||||
                        IKyberHintHandler.TradeType.MaskIn,
 | 
			
		||||
                        selectedReserves,
 | 
			
		||||
                        emptySplits
 | 
			
		||||
                    )
 | 
			
		||||
                returns (bytes memory result)
 | 
			
		||||
            {
 | 
			
		||||
                return result;
 | 
			
		||||
            } catch (bytes memory) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _sampleSellForApproximateBuyFromKyber(
 | 
			
		||||
        bytes memory takerTokenData,
 | 
			
		||||
        bytes memory makerTokenData,
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    )
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256)
 | 
			
		||||
    {
 | 
			
		||||
        (address makerToken, KyberSamplerOpts memory opts) =
 | 
			
		||||
            abi.decode(makerTokenData, (address, KyberSamplerOpts));
 | 
			
		||||
        (address takerToken, ) =
 | 
			
		||||
            abi.decode(takerTokenData, (address, KyberSamplerOpts));
 | 
			
		||||
        try
 | 
			
		||||
            this.sampleSellFromKyberNetwork
 | 
			
		||||
                (opts, takerToken, makerToken, sellAmount)
 | 
			
		||||
            returns (uint256 amount)
 | 
			
		||||
        {
 | 
			
		||||
            return amount;
 | 
			
		||||
        } catch (bytes memory) {
 | 
			
		||||
            // Swallow failures, leaving all results as zero.
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function sampleSellFromKyberNetwork(
 | 
			
		||||
        KyberSamplerOpts memory opts,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256 takerTokenAmount
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 makerTokenAmount)
 | 
			
		||||
    {
 | 
			
		||||
        // If there is no hint do not continue
 | 
			
		||||
        if (opts.hint.length == 0) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
            IKyberNetworkProxy(opts.networkProxy).getExpectedRateAfterFee
 | 
			
		||||
                {gas: KYBER_CALL_GAS}
 | 
			
		||||
                (
 | 
			
		||||
                    takerToken == opts.weth ? KYBER_ETH_ADDRESS : takerToken,
 | 
			
		||||
                    makerToken == opts.weth ? KYBER_ETH_ADDRESS : makerToken,
 | 
			
		||||
                    takerTokenAmount,
 | 
			
		||||
                    0, // fee
 | 
			
		||||
                    opts.hint
 | 
			
		||||
                )
 | 
			
		||||
            returns (uint256 rate)
 | 
			
		||||
        {
 | 
			
		||||
            uint256 makerTokenDecimals = _getTokenDecimals(makerToken);
 | 
			
		||||
            uint256 takerTokenDecimals = _getTokenDecimals(takerToken);
 | 
			
		||||
            makerTokenAmount =
 | 
			
		||||
                rate *
 | 
			
		||||
                takerTokenAmount *
 | 
			
		||||
                10 ** makerTokenDecimals /
 | 
			
		||||
                10 ** takerTokenDecimals /
 | 
			
		||||
                10 ** 18;
 | 
			
		||||
            return makerTokenAmount;
 | 
			
		||||
        } catch (bytes memory) {
 | 
			
		||||
            // Swallow failures, leaving all results as zero.
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _getNextReserveId(
 | 
			
		||||
        KyberSamplerOpts memory opts,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes32 reserveId)
 | 
			
		||||
    {
 | 
			
		||||
        // Fetch the registered reserves for this pair
 | 
			
		||||
        IKyberHintHandler kyberHint = IKyberHintHandler(opts.hintHandler);
 | 
			
		||||
        (bytes32[] memory reserveIds, ,) = kyberHint.getTradingReserves(
 | 
			
		||||
            takerToken == opts.weth ? KYBER_ETH_ADDRESS : takerToken,
 | 
			
		||||
            makerToken == opts.weth ? KYBER_ETH_ADDRESS : makerToken,
 | 
			
		||||
            true,
 | 
			
		||||
            new bytes(0) // empty hint
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (opts.reserveOffset >= reserveIds.length) {
 | 
			
		||||
            return 0x0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        reserveId = reserveIds[opts.reserveOffset];
 | 
			
		||||
        // Ignore Kyber Bridged Reserves (0xbb)
 | 
			
		||||
        if (uint256(reserveId >> 248) == 0xbb) {
 | 
			
		||||
            return 0x0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return reserveId;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,10 +22,18 @@ pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./SamplerUtils.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IWstETH {
 | 
			
		||||
    function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256);
 | 
			
		||||
    function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract LidoSampler is SamplerUtils {
 | 
			
		||||
    struct LidoInfo {
 | 
			
		||||
        address stEthToken;
 | 
			
		||||
        address wethToken;
 | 
			
		||||
        address wstEthToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from Lido
 | 
			
		||||
@@ -42,20 +50,17 @@ contract LidoSampler is SamplerUtils {
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        pure
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory)
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
 | 
			
		||||
        if (takerToken != lidoInfo.wethToken || makerToken != address(lidoInfo.stEthToken)) {
 | 
			
		||||
            // Return 0 values if not selling WETH for stETH
 | 
			
		||||
            uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
            uint256[] memory makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
            return makerTokenAmounts;
 | 
			
		||||
        if (takerToken == lidoInfo.wethToken && makerToken == address(lidoInfo.stEthToken)) {
 | 
			
		||||
            // Minting stETH is always 1:1 therefore we can just return the same amounts back.
 | 
			
		||||
            return takerTokenAmounts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Minting stETH is always 1:1 therefore we can just return the same amounts back
 | 
			
		||||
        return takerTokenAmounts;
 | 
			
		||||
        return _sampleSellsForWrapped(lidoInfo, takerToken, makerToken, takerTokenAmounts);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample buy quotes from Lido.
 | 
			
		||||
@@ -72,20 +77,43 @@ contract LidoSampler is SamplerUtils {
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        pure
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory)
 | 
			
		||||
    {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
 | 
			
		||||
        if (takerToken != lidoInfo.wethToken || makerToken != address(lidoInfo.stEthToken)) {
 | 
			
		||||
            // Return 0 values if not buying stETH for WETH
 | 
			
		||||
            uint256 numSamples = makerTokenAmounts.length;
 | 
			
		||||
            uint256[] memory takerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
            return takerTokenAmounts;
 | 
			
		||||
        if (takerToken == lidoInfo.wethToken && makerToken == address(lidoInfo.stEthToken)) {
 | 
			
		||||
            // Minting stETH is always 1:1 therefore we can just return the same amounts back.
 | 
			
		||||
            return makerTokenAmounts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Minting stETH is always 1:1 therefore we can just return the same amounts back
 | 
			
		||||
        return makerTokenAmounts;
 | 
			
		||||
        // Swap out `makerToken` and `takerToken` and re-use `_sampleSellsForWrapped`.
 | 
			
		||||
        return _sampleSellsForWrapped(lidoInfo, makerToken, takerToken, makerTokenAmounts);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _sampleSellsForWrapped(
 | 
			
		||||
        LidoInfo memory lidoInfo,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    ) private view  returns (uint256[] memory) {
 | 
			
		||||
        IWstETH wstETH = IWstETH(lidoInfo.wstEthToken);
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        uint256[] memory makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
 | 
			
		||||
        if (takerToken == lidoInfo.stEthToken && makerToken == lidoInfo.wstEthToken) {
 | 
			
		||||
            for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
                makerTokenAmounts[i] = wstETH.getWstETHByStETH(takerTokenAmounts[i]);
 | 
			
		||||
            }
 | 
			
		||||
            return makerTokenAmounts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (takerToken == lidoInfo.wstEthToken && makerToken == lidoInfo.stEthToken) {
 | 
			
		||||
            for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
                makerTokenAmounts[i] = wstETH.getStETHByWstETH(takerTokenAmounts[i]);
 | 
			
		||||
            }
 | 
			
		||||
            return makerTokenAmounts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Returns 0 values.
 | 
			
		||||
        return makerTokenAmounts;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IMultiBridge.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract MultiBridgeSampler {
 | 
			
		||||
 | 
			
		||||
    /// @dev Default gas limit for multibridge calls.
 | 
			
		||||
    uint256 constant private DEFAULT_CALL_GAS = 400e3; // 400k
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample sell quotes from MultiBridge.
 | 
			
		||||
    /// @param multibridge Address of the MultiBridge contract.
 | 
			
		||||
    /// @param takerToken Address of the taker token (what to sell).
 | 
			
		||||
    /// @param intermediateToken The address of the intermediate token to
 | 
			
		||||
    ///        use in an indirect route.
 | 
			
		||||
    /// @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 sampleSellsFromMultiBridge(
 | 
			
		||||
        address multibridge,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address intermediateToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        // Initialize array of maker token amounts.
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
 | 
			
		||||
        // If no address provided, return all zeros.
 | 
			
		||||
        if (multibridge == address(0)) {
 | 
			
		||||
            return makerTokenAmounts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            (bool didSucceed, bytes memory resultData) =
 | 
			
		||||
                multibridge.staticcall.gas(DEFAULT_CALL_GAS)(
 | 
			
		||||
                    abi.encodeWithSelector(
 | 
			
		||||
                        IMultiBridge(0).getSellQuote.selector,
 | 
			
		||||
                        takerToken,
 | 
			
		||||
                        intermediateToken,
 | 
			
		||||
                        makerToken,
 | 
			
		||||
                        takerTokenAmounts[i]
 | 
			
		||||
                    ));
 | 
			
		||||
            uint256 buyAmount = 0;
 | 
			
		||||
            if (didSucceed) {
 | 
			
		||||
                buyAmount = abi.decode(resultData, (uint256));
 | 
			
		||||
            }
 | 
			
		||||
            // Exit early if the amount is too high for the source to serve
 | 
			
		||||
            if (buyAmount == 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            makerTokenAmounts[i] = buyAmount;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										89
									
								
								packages/asset-swapper/contracts/src/PlatypusSampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								packages/asset-swapper/contracts/src/PlatypusSampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "./interfaces/IPlatypus.sol";
 | 
			
		||||
import "./ApproximateBuys.sol";
 | 
			
		||||
import "./SamplerUtils.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract PlatypusSampler is
 | 
			
		||||
    SamplerUtils,
 | 
			
		||||
    ApproximateBuys
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    function sampleSellsFromPlatypus(
 | 
			
		||||
        address pool,
 | 
			
		||||
        address[] memory path,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory makerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            try
 | 
			
		||||
                IPlatypus(pool).quotePotentialSwap(path[0], path[1], takerTokenAmounts[i])
 | 
			
		||||
                returns (uint256 amountAfterFees, uint256 feeAmount)
 | 
			
		||||
            {
 | 
			
		||||
                makerTokenAmounts[i] = amountAfterFees;
 | 
			
		||||
                // Break early if there are 0 amounts
 | 
			
		||||
                if (makerTokenAmounts[i] == 0) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            } catch (bytes memory result) {
 | 
			
		||||
                // Swallow failures, leaving all results as zero.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function sampleBuysFromPlatypus(
 | 
			
		||||
        address pool,
 | 
			
		||||
        address[] memory path,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    )
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory takerTokenAmounts)
 | 
			
		||||
    {
 | 
			
		||||
        address[] memory invertBuyPath = new address[](2);
 | 
			
		||||
        invertBuyPath[0] = path[1];
 | 
			
		||||
        invertBuyPath[1] = path[0];
 | 
			
		||||
        return _sampleApproximateBuys(
 | 
			
		||||
                ApproximateBuyQuoteOpts({
 | 
			
		||||
                    makerTokenData: abi.encode(pool, invertBuyPath),
 | 
			
		||||
                    takerTokenData: abi.encode(pool, path),
 | 
			
		||||
                    getSellQuoteCallback: _sampleSellForApproximateBuyFromPlatypus
 | 
			
		||||
                }),
 | 
			
		||||
                makerTokenAmounts
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function _sampleSellForApproximateBuyFromPlatypus(
 | 
			
		||||
        bytes memory makerTokenData,
 | 
			
		||||
        bytes memory takerTokenData,
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    )
 | 
			
		||||
        private
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 buyAmount)
 | 
			
		||||
    {
 | 
			
		||||
        (address _pool, address[] memory _path ) = abi.decode(makerTokenData, (address, address[]));
 | 
			
		||||
 | 
			
		||||
        (bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector(
 | 
			
		||||
            this.sampleSellsFromPlatypus.selector,
 | 
			
		||||
            _pool,
 | 
			
		||||
            _path,
 | 
			
		||||
            _toSingleValueArray(sellAmount)
 | 
			
		||||
        ));
 | 
			
		||||
        if(!success) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        // solhint-disable-next-line indent
 | 
			
		||||
        return abi.decode(resultData, (uint256[]))[0];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								packages/asset-swapper/contracts/src/VelodromeSampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								packages/asset-swapper/contracts/src/VelodromeSampler.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import './ApproximateBuys.sol';
 | 
			
		||||
import './SamplerUtils.sol';
 | 
			
		||||
 | 
			
		||||
struct VeloRoute {
 | 
			
		||||
    address from;
 | 
			
		||||
    address to;
 | 
			
		||||
    bool stable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IVelodromeRouter {
 | 
			
		||||
    function getAmountOut(
 | 
			
		||||
        uint256 amountIn,
 | 
			
		||||
        address tokenIn,
 | 
			
		||||
        address tokenOut
 | 
			
		||||
    ) external view returns (uint256 amount, bool stable);
 | 
			
		||||
 | 
			
		||||
    function getAmountsOut(uint256 amountIn, VeloRoute[] calldata routes)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory amounts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract VelodromeSampler is SamplerUtils, ApproximateBuys {
 | 
			
		||||
    /// @dev Sample sell quotes from Velodrome
 | 
			
		||||
    /// @param router Address of Velodrome router.
 | 
			
		||||
    /// @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 (sorted in ascending order).
 | 
			
		||||
    /// @return stable Whether the pool is a stable pool (vs volatile).
 | 
			
		||||
    /// @return makerTokenAmounts Maker amounts bought at each taker token amount.
 | 
			
		||||
    function sampleSellsFromVelodrome(
 | 
			
		||||
        IVelodromeRouter router,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    ) public view returns (bool stable, uint256[] memory makerTokenAmounts) {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
			
		||||
 | 
			
		||||
        // Sampling should not mix stable and volatile pools.
 | 
			
		||||
        // Find the most liquid pool based on max(takerTokenAmounts) and stick with it.
 | 
			
		||||
        stable = _isMostLiquidPoolStablePool(router, takerToken, makerToken, takerTokenAmounts);
 | 
			
		||||
        VeloRoute[] memory routes = new VeloRoute[](1);
 | 
			
		||||
        routes[0] = VeloRoute({ from: takerToken, to: makerToken, stable: stable });
 | 
			
		||||
 | 
			
		||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
			
		||||
            makerTokenAmounts[i] = router.getAmountsOut(takerTokenAmounts[i], routes)[1];
 | 
			
		||||
            // Break early if there are 0 amounts
 | 
			
		||||
            if (makerTokenAmounts[i] == 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Sample buy quotes from Velodrome.
 | 
			
		||||
    /// @param router Address of Velodrome router.
 | 
			
		||||
    /// @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 stable Whether the pool is a stable pool (vs volatile).
 | 
			
		||||
    /// @return takerTokenAmounts Taker amounts sold at each maker token amount.
 | 
			
		||||
    function sampleBuysFromVelodrome(
 | 
			
		||||
        IVelodromeRouter router,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory makerTokenAmounts
 | 
			
		||||
    ) public view returns (bool stable, uint256[] memory takerTokenAmounts) {
 | 
			
		||||
        _assertValidPair(makerToken, takerToken);
 | 
			
		||||
 | 
			
		||||
        // Sampling should not mix stable and volatile pools.
 | 
			
		||||
        // Find the most liquid pool based on the reverse swap (maker -> taker) and stick with it.
 | 
			
		||||
        stable = _isMostLiquidPoolStablePool(router, makerToken, takerToken, makerTokenAmounts);
 | 
			
		||||
 | 
			
		||||
        takerTokenAmounts = _sampleApproximateBuys(
 | 
			
		||||
            ApproximateBuyQuoteOpts({
 | 
			
		||||
                takerTokenData: abi.encode(router, VeloRoute({ from: takerToken, to: makerToken, stable: stable })),
 | 
			
		||||
                makerTokenData: abi.encode(router, VeloRoute({ from: makerToken, to: takerToken, stable: stable })),
 | 
			
		||||
                getSellQuoteCallback: _sampleSellForApproximateBuyFromVelodrome
 | 
			
		||||
            }),
 | 
			
		||||
            makerTokenAmounts
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _sampleSellForApproximateBuyFromVelodrome(
 | 
			
		||||
        bytes memory takerTokenData,
 | 
			
		||||
        bytes memory, /* makerTokenData */
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    ) internal view returns (uint256) {
 | 
			
		||||
        (IVelodromeRouter router, VeloRoute memory route) = abi.decode(takerTokenData, (IVelodromeRouter, VeloRoute));
 | 
			
		||||
 | 
			
		||||
        VeloRoute[] memory routes = new VeloRoute[](1);
 | 
			
		||||
        routes[0] = route;
 | 
			
		||||
        return router.getAmountsOut(sellAmount, routes)[1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Returns whether the most liquid pool is a stable pool.
 | 
			
		||||
    /// @param router Address of Velodrome router.
 | 
			
		||||
    /// @param takerToken Address of the taker token (what to sell).
 | 
			
		||||
    /// @param makerToken Address of the maker token (what to buy).
 | 
			
		||||
    /// @param takerTokenAmounts Taker token buy amount for each sample (sorted in ascending order)
 | 
			
		||||
    /// @return stable Whether the pool is a stable pool (vs volatile).
 | 
			
		||||
    function _isMostLiquidPoolStablePool(
 | 
			
		||||
        IVelodromeRouter router,
 | 
			
		||||
        address takerToken,
 | 
			
		||||
        address makerToken,
 | 
			
		||||
        uint256[] memory takerTokenAmounts
 | 
			
		||||
    ) internal view returns (bool stable) {
 | 
			
		||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
			
		||||
        (, stable) = router.getAmountOut(takerTokenAmounts[numSamples - 1], takerToken, makerToken);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,54 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
/// @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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct BalancerV2PoolInfo {
 | 
			
		||||
        bytes32 poolId;
 | 
			
		||||
        address vault;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function queryBatchSwap(
 | 
			
		||||
        SwapKind kind,
 | 
			
		||||
        BatchSwapStep[] calldata swaps,
 | 
			
		||||
        address[] calldata assets,
 | 
			
		||||
        FundManagement calldata funds
 | 
			
		||||
    ) external returns (int256[] memory assetDeltas);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2022 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
interface IBancorV3 {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @dev returns the output amount when trading by providing the source amount
 | 
			
		||||
     */
 | 
			
		||||
    function tradeOutputBySourceAmount(
 | 
			
		||||
        address sourceToken,
 | 
			
		||||
        address targetToken,
 | 
			
		||||
        uint256 sourceAmount
 | 
			
		||||
    ) external view returns (uint256);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @dev returns the input amount when trading by providing the target amount
 | 
			
		||||
     */
 | 
			
		||||
    function tradeInputByTargetAmount(
 | 
			
		||||
        address sourceToken,
 | 
			
		||||
        address targetToken,
 | 
			
		||||
        uint256 targetAmount
 | 
			
		||||
    ) external view returns (uint256);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								packages/asset-swapper/contracts/src/interfaces/IGMX.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/asset-swapper/contracts/src/interfaces/IGMX.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
interface IGMX {
 | 
			
		||||
    function getMaxAmountIn(IVault _vault, address _tokenIn, address _tokenOut)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256);
 | 
			
		||||
 | 
			
		||||
    function getAmountOut(IVault _vault, address _tokenIn, address _tokenOut, uint256 _amountIn)
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256, uint256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IVault {
 | 
			
		||||
    function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256);
 | 
			
		||||
    function stableSwapFeeBasisPoints() external view returns (uint256);
 | 
			
		||||
    function stableTokens(address _token) external view returns (bool);
 | 
			
		||||
    function tokenDecimals(address _token) external view returns (uint256);
 | 
			
		||||
    function getMaxPrice(address _token) external view returns (uint256);
 | 
			
		||||
    function getMinPrice(address _token) external view returns (uint256);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
 | 
			
		||||
// Keepin everything together
 | 
			
		||||
interface IKyberNetwork {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface IKyberNetworkProxy {
 | 
			
		||||
 | 
			
		||||
    function getExpectedRateAfterFee(
 | 
			
		||||
        address src,
 | 
			
		||||
        address dest,
 | 
			
		||||
        uint256 srcQty,
 | 
			
		||||
        uint256 platformFeeBps,
 | 
			
		||||
        bytes calldata hint
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 expectedRate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IKyberHintHandler {
 | 
			
		||||
 | 
			
		||||
    enum TradeType {BestOfAll, MaskIn, MaskOut, Split}
 | 
			
		||||
 | 
			
		||||
    enum ProcessWithRate {NotRequired, Required}
 | 
			
		||||
 | 
			
		||||
    function getTradingReserves(
 | 
			
		||||
        address tokenSrc,
 | 
			
		||||
        address tokenDest,
 | 
			
		||||
        bool isTokenToToken,
 | 
			
		||||
        bytes calldata hint
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (
 | 
			
		||||
            bytes32[] memory reserveIds,
 | 
			
		||||
            uint256[] memory splitValuesBps,
 | 
			
		||||
            ProcessWithRate processWithRate
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    function buildTokenToEthHint(
 | 
			
		||||
        address tokenSrc,
 | 
			
		||||
        TradeType tokenToEthType,
 | 
			
		||||
        bytes32[] calldata tokenToEthReserveIds,
 | 
			
		||||
        uint256[] calldata tokenToEthSplits
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes memory hint);
 | 
			
		||||
 | 
			
		||||
    function buildEthToTokenHint(
 | 
			
		||||
        address tokenDest,
 | 
			
		||||
        TradeType ethToTokenType,
 | 
			
		||||
        bytes32[] calldata ethToTokenReserveIds,
 | 
			
		||||
        uint256[] calldata ethToTokenSplits
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes memory hint);
 | 
			
		||||
 | 
			
		||||
    function buildTokenToTokenHint(
 | 
			
		||||
        address tokenSrc,
 | 
			
		||||
        TradeType tokenToEthType,
 | 
			
		||||
        bytes32[] calldata tokenToEthReserveIds,
 | 
			
		||||
        uint256[] calldata tokenToEthSplits,
 | 
			
		||||
        address tokenDest,
 | 
			
		||||
        TradeType ethToTokenType,
 | 
			
		||||
        bytes32[] calldata ethToTokenReserveIds,
 | 
			
		||||
        uint256[] calldata ethToTokenSplits
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (bytes memory hint);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
 | 
			
		||||
interface IPlatypus {
 | 
			
		||||
    function quotePotentialSwap(
 | 
			
		||||
        address fromToken,
 | 
			
		||||
        address toToken,
 | 
			
		||||
        uint256 fromAmount
 | 
			
		||||
    ) external view returns (uint256 potentialOutcome, uint256 haircut);
 | 
			
		||||
 | 
			
		||||
    function assetOf(address token) external view returns (address);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,39 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract DummyLiquidityProvider
 | 
			
		||||
{
 | 
			
		||||
    /// @dev Quotes the amount of `makerToken` that would be obtained by
 | 
			
		||||
    ///      selling `sellAmount` of `takerToken`.
 | 
			
		||||
    /// @param sellAmount Amount of `takerToken` to sell.
 | 
			
		||||
    /// @return makerTokenAmount Amount of `makerToken` that would be obtained.
 | 
			
		||||
    function getSellQuote(
 | 
			
		||||
        address, /* takerToken */
 | 
			
		||||
        address, /* makerToken */
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 makerTokenAmount)
 | 
			
		||||
    {
 | 
			
		||||
        makerTokenAmount = sellAmount - 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Quotes the amount of `takerToken` that would need to be sold in
 | 
			
		||||
    ///      order to obtain `buyAmount` of `makerToken`.
 | 
			
		||||
    /// @param buyAmount Amount of `makerToken` to buy.
 | 
			
		||||
    /// @return takerTokenAmount Amount of `takerToken` that would need to be sold.
 | 
			
		||||
    function getBuyQuote(
 | 
			
		||||
        address, /* takerToken */
 | 
			
		||||
        address, /* makerToken */
 | 
			
		||||
        uint256 buyAmount
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 takerTokenAmount)
 | 
			
		||||
    {
 | 
			
		||||
        takerTokenAmount = buyAmount + 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,455 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 ZeroEx Intl.
 | 
			
		||||
 | 
			
		||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
  you may not use this file except in compliance with the License.
 | 
			
		||||
  You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
  See the License for the specific language governing permissions and
 | 
			
		||||
  limitations under the License.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
pragma solidity ^0.6;
 | 
			
		||||
pragma experimental ABIEncoderV2;
 | 
			
		||||
 | 
			
		||||
import "../src/ERC20BridgeSampler.sol";
 | 
			
		||||
import "../src/interfaces/IKyberNetwork.sol";
 | 
			
		||||
import "../src/interfaces/IUniswapV2Router01.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
library LibDeterministicQuotes {
 | 
			
		||||
 | 
			
		||||
    address private constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
 | 
			
		||||
    uint256 private constant RATE_DENOMINATOR = 1 ether;
 | 
			
		||||
    uint256 private constant MIN_RATE = RATE_DENOMINATOR / 100;
 | 
			
		||||
    uint256 private constant MAX_RATE = 100 * RATE_DENOMINATOR;
 | 
			
		||||
    uint8 private constant MIN_DECIMALS = 4;
 | 
			
		||||
    uint8 private constant MAX_DECIMALS = 20;
 | 
			
		||||
 | 
			
		||||
    function getDeterministicSellQuote(
 | 
			
		||||
        bytes32 salt,
 | 
			
		||||
        address sellToken,
 | 
			
		||||
        address buyToken,
 | 
			
		||||
        uint256 sellAmount
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (uint256 buyAmount)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 sellBase = uint256(10) ** getDeterministicTokenDecimals(sellToken);
 | 
			
		||||
        uint256 buyBase = uint256(10) ** getDeterministicTokenDecimals(buyToken);
 | 
			
		||||
        uint256 rate = getDeterministicRate(salt, sellToken, buyToken);
 | 
			
		||||
        return sellAmount * rate * buyBase / sellBase / RATE_DENOMINATOR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getDeterministicBuyQuote(
 | 
			
		||||
        bytes32 salt,
 | 
			
		||||
        address sellToken,
 | 
			
		||||
        address buyToken,
 | 
			
		||||
        uint256 buyAmount
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (uint256 sellAmount)
 | 
			
		||||
    {
 | 
			
		||||
        uint256 sellBase = uint256(10) ** getDeterministicTokenDecimals(sellToken);
 | 
			
		||||
        uint256 buyBase = uint256(10) ** getDeterministicTokenDecimals(buyToken);
 | 
			
		||||
        uint256 rate = getDeterministicRate(salt, sellToken, buyToken);
 | 
			
		||||
        return buyAmount * RATE_DENOMINATOR * sellBase / rate / buyBase;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getDeterministicTokenDecimals(address token)
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (uint8 decimals)
 | 
			
		||||
    {
 | 
			
		||||
        if (token == WETH_ADDRESS) {
 | 
			
		||||
            return 18;
 | 
			
		||||
        }
 | 
			
		||||
        bytes32 seed = keccak256(abi.encodePacked(token));
 | 
			
		||||
        return uint8(uint256(seed) % (MAX_DECIMALS - MIN_DECIMALS)) + MIN_DECIMALS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getDeterministicRate(bytes32 salt, address sellToken, address buyToken)
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (uint256 rate)
 | 
			
		||||
    {
 | 
			
		||||
        bytes32 seed = keccak256(abi.encodePacked(salt, sellToken, buyToken));
 | 
			
		||||
        return uint256(seed) % (MAX_RATE - MIN_RATE) + MIN_RATE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract TestDeploymentConstants {
 | 
			
		||||
 | 
			
		||||
    // solhint-disable separate-by-one-line-in-contract
 | 
			
		||||
 | 
			
		||||
    // Mainnet addresses ///////////////////////////////////////////////////////
 | 
			
		||||
    /// @dev Mainnet address of the WETH contract.
 | 
			
		||||
    address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
 | 
			
		||||
 | 
			
		||||
    /// @dev Overridable way to get the WETH address.
 | 
			
		||||
    /// @return wethAddress The WETH address.
 | 
			
		||||
    function _getWethAddress()
 | 
			
		||||
        internal
 | 
			
		||||
        view
 | 
			
		||||
        returns (address wethAddress)
 | 
			
		||||
    {
 | 
			
		||||
        return WETH_ADDRESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
contract FailTrigger {
 | 
			
		||||
 | 
			
		||||
    // Give this address a balance to force operations to fail.
 | 
			
		||||
    address payable constant public FAILURE_ADDRESS = 0xe9dB8717BC5DFB20aaf538b4a5a02B7791FF430C;
 | 
			
		||||
 | 
			
		||||
    // Funds `FAILURE_ADDRESS`.
 | 
			
		||||
    function enableFailTrigger() external payable {
 | 
			
		||||
        FAILURE_ADDRESS.transfer(msg.value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function _revertIfShouldFail() internal view {
 | 
			
		||||
        if (FAILURE_ADDRESS.balance != 0) {
 | 
			
		||||
            revert("FAIL_TRIGGERED");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestERC20BridgeSamplerUniswapExchange is
 | 
			
		||||
    IUniswapExchangeQuotes,
 | 
			
		||||
    TestDeploymentConstants,
 | 
			
		||||
    FailTrigger
 | 
			
		||||
{
 | 
			
		||||
    bytes32 constant private BASE_SALT = 0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab;
 | 
			
		||||
 | 
			
		||||
    address public tokenAddress;
 | 
			
		||||
    bytes32 public salt;
 | 
			
		||||
 | 
			
		||||
    constructor(address _tokenAddress) public {
 | 
			
		||||
        tokenAddress = _tokenAddress;
 | 
			
		||||
        salt = keccak256(abi.encodePacked(BASE_SALT, _tokenAddress));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IUniswapExchangeQuotes.getEthToTokenInputPrice()`.
 | 
			
		||||
    function getEthToTokenInputPrice(
 | 
			
		||||
        uint256 ethSold
 | 
			
		||||
    )
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 tokensBought)
 | 
			
		||||
    {
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        return LibDeterministicQuotes.getDeterministicSellQuote(
 | 
			
		||||
            salt,
 | 
			
		||||
            tokenAddress,
 | 
			
		||||
            _getWethAddress(),
 | 
			
		||||
            ethSold
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IUniswapExchangeQuotes.getEthToTokenOutputPrice()`.
 | 
			
		||||
    function getEthToTokenOutputPrice(
 | 
			
		||||
        uint256 tokensBought
 | 
			
		||||
    )
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 ethSold)
 | 
			
		||||
    {
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        return LibDeterministicQuotes.getDeterministicBuyQuote(
 | 
			
		||||
            salt,
 | 
			
		||||
            _getWethAddress(),
 | 
			
		||||
            tokenAddress,
 | 
			
		||||
            tokensBought
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IUniswapExchangeQuotes.getTokenToEthInputPrice()`.
 | 
			
		||||
    function getTokenToEthInputPrice(
 | 
			
		||||
        uint256 tokensSold
 | 
			
		||||
    )
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 ethBought)
 | 
			
		||||
    {
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        return LibDeterministicQuotes.getDeterministicSellQuote(
 | 
			
		||||
            salt,
 | 
			
		||||
            tokenAddress,
 | 
			
		||||
            _getWethAddress(),
 | 
			
		||||
            tokensSold
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IUniswapExchangeQuotes.getTokenToEthOutputPrice()`.
 | 
			
		||||
    function getTokenToEthOutputPrice(
 | 
			
		||||
        uint256 ethBought
 | 
			
		||||
    )
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 tokensSold)
 | 
			
		||||
    {
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        return LibDeterministicQuotes.getDeterministicBuyQuote(
 | 
			
		||||
            salt,
 | 
			
		||||
            _getWethAddress(),
 | 
			
		||||
            tokenAddress,
 | 
			
		||||
            ethBought
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestERC20BridgeSamplerUniswapV2Router01 is
 | 
			
		||||
    IUniswapV2Router01,
 | 
			
		||||
    TestDeploymentConstants,
 | 
			
		||||
    FailTrigger
 | 
			
		||||
{
 | 
			
		||||
    bytes32 constant private SALT = 0xadc7fcb33c735913b8635927e66896b356a53a912ab2ceff929e60a04b53b3c1;
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IUniswapV2Router01.getAmountsOut()`.
 | 
			
		||||
    function getAmountsOut(uint256 amountIn, address[] calldata path)
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory amounts)
 | 
			
		||||
    {
 | 
			
		||||
        require(path.length >= 2, "PATH_TOO_SHORT");
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        amounts = new uint256[](path.length);
 | 
			
		||||
        amounts[0] = amountIn;
 | 
			
		||||
        for (uint256 i = 0; i < path.length - 1; ++i) {
 | 
			
		||||
            amounts[i + 1] = LibDeterministicQuotes.getDeterministicSellQuote(
 | 
			
		||||
                SALT,
 | 
			
		||||
                path[i],
 | 
			
		||||
                path[i + 1],
 | 
			
		||||
                amounts[i]
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IUniswapV2Router01.getAmountsInt()`.
 | 
			
		||||
    function getAmountsIn(uint256 amountOut, address[] calldata path)
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256[] memory amounts)
 | 
			
		||||
    {
 | 
			
		||||
        require(path.length >= 2, "PATH_TOO_SHORT");
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        amounts = new uint256[](path.length);
 | 
			
		||||
        amounts[path.length - 1] = amountOut;
 | 
			
		||||
        for (uint256 i = path.length - 1; i > 0; --i) {
 | 
			
		||||
            amounts[i - 1] = LibDeterministicQuotes.getDeterministicBuyQuote(
 | 
			
		||||
                SALT,
 | 
			
		||||
                path[i - 1],
 | 
			
		||||
                path[i],
 | 
			
		||||
                amounts[i]
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// solhint-disable space-after-comma
 | 
			
		||||
contract TestERC20BridgeSamplerKyberNetwork is
 | 
			
		||||
    TestDeploymentConstants,
 | 
			
		||||
    FailTrigger
 | 
			
		||||
{
 | 
			
		||||
    bytes32 constant private SALT = 0x0ff3ca9d46195c39f9a12afb74207b4970349fb3cfb1e459bbf170298d326bc7;
 | 
			
		||||
    address constant public ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
 | 
			
		||||
 | 
			
		||||
    enum TradeType {BestOfAll, MaskIn, MaskOut, Split}
 | 
			
		||||
    enum ProcessWithRate {NotRequired, Required}
 | 
			
		||||
 | 
			
		||||
    // IKyberHintHandler
 | 
			
		||||
    function buildTokenToEthHint(
 | 
			
		||||
        address tokenSrc,
 | 
			
		||||
        TradeType /* tokenToEthType */,
 | 
			
		||||
        bytes32[] calldata /* tokenToEthReserveIds */,
 | 
			
		||||
        uint256[] calldata /* tokenToEthSplits */
 | 
			
		||||
    ) external view returns (bytes memory hint)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encode(tokenSrc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function buildEthToTokenHint(
 | 
			
		||||
        address tokenDest,
 | 
			
		||||
        TradeType /* ethToTokenType */,
 | 
			
		||||
        bytes32[] calldata /* ethToTokenReserveIds */,
 | 
			
		||||
        uint256[] calldata /* ethToTokenSplits */
 | 
			
		||||
    ) external view returns (bytes memory hint)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encode(tokenDest);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // IKyberHintHandler
 | 
			
		||||
    function buildTokenToTokenHint(
 | 
			
		||||
        address tokenSrc,
 | 
			
		||||
        TradeType /* tokenToEthType */,
 | 
			
		||||
        bytes32[] calldata /* tokenToEthReserveIds */,
 | 
			
		||||
        uint256[] calldata /* tokenToEthSplits */,
 | 
			
		||||
        address /* tokenDest  */,
 | 
			
		||||
        TradeType /* EthToTokenType */,
 | 
			
		||||
        bytes32[] calldata /* EthToTokenReserveIds */,
 | 
			
		||||
        uint256[] calldata /* EthToTokenSplits */
 | 
			
		||||
    ) external view returns (bytes memory hint)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encode(tokenSrc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // IKyberHintHandler
 | 
			
		||||
    function getTradingReserves(
 | 
			
		||||
        address tokenSrc,
 | 
			
		||||
        address tokenDest,
 | 
			
		||||
        bool isTokenToToken,
 | 
			
		||||
        bytes calldata hint
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (
 | 
			
		||||
            bytes32[] memory reserveIds,
 | 
			
		||||
            uint256[] memory splitValuesBps,
 | 
			
		||||
            ProcessWithRate processWithRate
 | 
			
		||||
        )
 | 
			
		||||
    {
 | 
			
		||||
        reserveIds = new bytes32[](1);
 | 
			
		||||
        reserveIds[0] = bytes32(uint256(1));
 | 
			
		||||
        splitValuesBps = new uint256[](0);
 | 
			
		||||
        processWithRate = ProcessWithRate.NotRequired;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IKyberNetworkProxy.getExpectedRateAfterFee()`.
 | 
			
		||||
    function getExpectedRateAfterFee(
 | 
			
		||||
        address fromToken,
 | 
			
		||||
        address toToken,
 | 
			
		||||
        uint256 /* srcQty */,
 | 
			
		||||
        uint256 /* fee */,
 | 
			
		||||
        bytes calldata /* hint */
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns
 | 
			
		||||
        (uint256 expectedRate)
 | 
			
		||||
    {
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        fromToken = fromToken == ETH_ADDRESS ? _getWethAddress() : fromToken;
 | 
			
		||||
        toToken = toToken == ETH_ADDRESS ? _getWethAddress() : toToken;
 | 
			
		||||
        expectedRate = LibDeterministicQuotes.getDeterministicRate(
 | 
			
		||||
            SALT,
 | 
			
		||||
            fromToken,
 | 
			
		||||
            toToken
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Deterministic `IKyberNetworkProxy.getExpectedRate()`.
 | 
			
		||||
    function getExpectedRate(
 | 
			
		||||
        address fromToken,
 | 
			
		||||
        address toToken,
 | 
			
		||||
        uint256
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 expectedRate, uint256)
 | 
			
		||||
    {
 | 
			
		||||
        _revertIfShouldFail();
 | 
			
		||||
        fromToken = fromToken == ETH_ADDRESS ? _getWethAddress() : fromToken;
 | 
			
		||||
        toToken = toToken == ETH_ADDRESS ? _getWethAddress() : toToken;
 | 
			
		||||
        expectedRate = LibDeterministicQuotes.getDeterministicRate(
 | 
			
		||||
            SALT,
 | 
			
		||||
            fromToken,
 | 
			
		||||
            toToken
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestERC20BridgeSamplerUniswapExchangeFactory is
 | 
			
		||||
    IUniswapExchangeFactory
 | 
			
		||||
{
 | 
			
		||||
    mapping (address => IUniswapExchangeQuotes) private _exchangesByToken;
 | 
			
		||||
 | 
			
		||||
    // Creates Uniswap exchange contracts for tokens.
 | 
			
		||||
    function createTokenExchanges(address[] calldata tokenAddresses)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        for (uint256 i = 0; i < tokenAddresses.length; i++) {
 | 
			
		||||
            address tokenAddress = tokenAddresses[i];
 | 
			
		||||
            _exchangesByToken[tokenAddress] =
 | 
			
		||||
                new TestERC20BridgeSamplerUniswapExchange(tokenAddress);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // `IUniswapExchangeFactory.getExchange()`.
 | 
			
		||||
    function getExchange(address tokenAddress)
 | 
			
		||||
        override
 | 
			
		||||
        external
 | 
			
		||||
        view
 | 
			
		||||
        returns (address)
 | 
			
		||||
    {
 | 
			
		||||
        return address(_exchangesByToken[tokenAddress]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestERC20BridgeSampler is
 | 
			
		||||
    ERC20BridgeSampler,
 | 
			
		||||
    FailTrigger
 | 
			
		||||
{
 | 
			
		||||
    TestERC20BridgeSamplerUniswapExchangeFactory public uniswap;
 | 
			
		||||
    TestERC20BridgeSamplerUniswapV2Router01 public uniswapV2Router;
 | 
			
		||||
    TestERC20BridgeSamplerKyberNetwork public kyber;
 | 
			
		||||
 | 
			
		||||
    uint8 private constant MAX_ORDER_STATUS = uint8(IExchange.OrderStatus.CANCELLED) + 1;
 | 
			
		||||
 | 
			
		||||
    constructor() public ERC20BridgeSampler() {
 | 
			
		||||
        uniswap = new TestERC20BridgeSamplerUniswapExchangeFactory();
 | 
			
		||||
        uniswapV2Router = new TestERC20BridgeSamplerUniswapV2Router01();
 | 
			
		||||
        kyber = new TestERC20BridgeSamplerKyberNetwork();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Creates Uniswap exchange contracts for tokens.
 | 
			
		||||
    function createTokenExchanges(address[] calldata tokenAddresses)
 | 
			
		||||
        external
 | 
			
		||||
    {
 | 
			
		||||
        uniswap.createTokenExchanges(tokenAddresses);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Overridden to return deterministic states.
 | 
			
		||||
    function getLimitOrderFillableTakerAmount(
 | 
			
		||||
        IExchange.LimitOrder memory order,
 | 
			
		||||
        IExchange.Signature memory,
 | 
			
		||||
        IExchange
 | 
			
		||||
    )
 | 
			
		||||
        override
 | 
			
		||||
        public
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint256 fillableTakerAmount)
 | 
			
		||||
    {
 | 
			
		||||
        return uint256(keccak256(abi.encode(order.salt))) % order.takerAmount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Overriden to return deterministic decimals.
 | 
			
		||||
    function _getTokenDecimals(address tokenAddress)
 | 
			
		||||
        override
 | 
			
		||||
        internal
 | 
			
		||||
        view
 | 
			
		||||
        returns (uint8 decimals)
 | 
			
		||||
    {
 | 
			
		||||
        return LibDeterministicQuotes.getDeterministicTokenDecimals(tokenAddress);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@0x/asset-swapper",
 | 
			
		||||
    "version": "16.50.3",
 | 
			
		||||
    "version": "16.62.0",
 | 
			
		||||
    "engines": {
 | 
			
		||||
        "node": ">=6.12"
 | 
			
		||||
    },
 | 
			
		||||
@@ -34,12 +34,13 @@
 | 
			
		||||
        "contracts:gen": "contracts-gen generate",
 | 
			
		||||
        "contracts:copy": "contracts-gen copy",
 | 
			
		||||
        "publish:private": "yarn build && gitpkg publish",
 | 
			
		||||
        "sampler-size": "jq .compilerOutput.evm.deployedBytecode.object  -- test/generated-artifacts/ERC20BridgeSampler.json | echo $(( $(wc -c) / 2 - 1 ))"
 | 
			
		||||
        "sampler-size": "jq .compilerOutput.evm.deployedBytecode.object  -- test/generated-artifacts/ERC20BridgeSampler.json | echo $(( $(wc -c) / 2 - 1 ))",
 | 
			
		||||
        "list:deps": "yarn lerna list -l"
 | 
			
		||||
    },
 | 
			
		||||
    "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|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|BancorV3Sampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|IBancorV3|ICurve|IGMX|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler|VelodromeSampler).json",
 | 
			
		||||
        "postpublish": {
 | 
			
		||||
            "assets": []
 | 
			
		||||
        }
 | 
			
		||||
@@ -58,22 +59,22 @@
 | 
			
		||||
        "registry": "git@github.com:0xProject/gitpkg-registry.git"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@0x/assert": "^3.0.31",
 | 
			
		||||
        "@0x/base-contract": "^6.4.5",
 | 
			
		||||
        "@0x/contract-addresses": "^6.12.0",
 | 
			
		||||
        "@0x/contract-wrappers": "^13.19.1",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.27",
 | 
			
		||||
        "@0x/contracts-zero-ex": "^0.31.1",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.11",
 | 
			
		||||
        "@0x/json-schemas": "^6.4.1",
 | 
			
		||||
        "@0x/assert": "^3.0.34",
 | 
			
		||||
        "@0x/base-contract": "^6.5.0",
 | 
			
		||||
        "@0x/contract-addresses": "^6.16.0",
 | 
			
		||||
        "@0x/contract-wrappers": "^13.20.4",
 | 
			
		||||
        "@0x/contracts-erc20": "^3.3.32",
 | 
			
		||||
        "@0x/contracts-zero-ex": "^0.35.0",
 | 
			
		||||
        "@0x/dev-utils": "^4.2.14",
 | 
			
		||||
        "@0x/json-schemas": "^6.4.4",
 | 
			
		||||
        "@0x/neon-router": "^0.3.5",
 | 
			
		||||
        "@0x/protocol-utils": "^1.11.1",
 | 
			
		||||
        "@0x/protocol-utils": "^11.15.0",
 | 
			
		||||
        "@0x/quote-server": "^6.0.6",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/typescript-typings": "^5.2.1",
 | 
			
		||||
        "@0x/utils": "^6.5.0",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.2",
 | 
			
		||||
        "@balancer-labs/sor": "0.3.2",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@0x/typescript-typings": "^5.3.1",
 | 
			
		||||
        "@0x/utils": "^6.5.3",
 | 
			
		||||
        "@0x/web3-wrapper": "^7.6.5",
 | 
			
		||||
        "@balancer-labs/sdk": "0.1.6",
 | 
			
		||||
        "@bancor/sdk": "0.2.9",
 | 
			
		||||
        "@ethersproject/abi": "^5.0.1",
 | 
			
		||||
        "@ethersproject/address": "^5.0.1",
 | 
			
		||||
@@ -82,9 +83,10 @@
 | 
			
		||||
        "@ethersproject/strings": "^5.0.10",
 | 
			
		||||
        "axios": "^0.21.1",
 | 
			
		||||
        "axios-mock-adapter": "^1.19.0",
 | 
			
		||||
        "balancer-labs-sor-v1": "npm:@balancer-labs/sor@0.3.2",
 | 
			
		||||
        "cream-sor": "^0.3.3",
 | 
			
		||||
        "decimal.js": "^10.2.0",
 | 
			
		||||
        "ethereum-types": "^3.6.0",
 | 
			
		||||
        "ethereum-types": "^3.7.0",
 | 
			
		||||
        "ethereumjs-util": "^7.0.10",
 | 
			
		||||
        "fast-abi": "^0.0.4",
 | 
			
		||||
        "graphql": "^15.4.0",
 | 
			
		||||
@@ -93,20 +95,19 @@
 | 
			
		||||
        "lodash": "^4.17.11"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "@0x/abi-gen": "^5.7.2",
 | 
			
		||||
        "@0x/abi-gen": "^5.8.0",
 | 
			
		||||
        "@0x/contracts-asset-proxy": "^3.7.19",
 | 
			
		||||
        "@0x/contracts-exchange": "^3.2.38",
 | 
			
		||||
        "@0x/contracts-exchange-libs": "^4.3.37",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.43",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.18",
 | 
			
		||||
        "@0x/contracts-utils": "^4.8.8",
 | 
			
		||||
        "@0x/contracts-gen": "^2.0.46",
 | 
			
		||||
        "@0x/contracts-test-utils": "^5.4.23",
 | 
			
		||||
        "@0x/contracts-utils": "^4.8.13",
 | 
			
		||||
        "@0x/mesh-rpc-client": "^9.4.2",
 | 
			
		||||
        "@0x/migrations": "^8.1.16",
 | 
			
		||||
        "@0x/sol-compiler": "^4.7.8",
 | 
			
		||||
        "@0x/subproviders": "^6.6.2",
 | 
			
		||||
        "@0x/sol-compiler": "^4.8.1",
 | 
			
		||||
        "@0x/subproviders": "^6.6.5",
 | 
			
		||||
        "@0x/ts-doc-gen": "^0.0.28",
 | 
			
		||||
        "@0x/tslint-config": "^4.1.4",
 | 
			
		||||
        "@0x/types": "^3.3.4",
 | 
			
		||||
        "@0x/types": "^3.3.6",
 | 
			
		||||
        "@types/lodash": "4.14.104",
 | 
			
		||||
        "@types/mocha": "^5.2.7",
 | 
			
		||||
        "@types/node": "12.12.54",
 | 
			
		||||
@@ -123,7 +124,7 @@
 | 
			
		||||
        "tslint": "5.11.0",
 | 
			
		||||
        "typedoc": "~0.16.11",
 | 
			
		||||
        "typemoq": "^2.1.0",
 | 
			
		||||
        "typescript": "4.2.2"
 | 
			
		||||
        "typescript": "4.6.3"
 | 
			
		||||
    },
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "access": "public"
 | 
			
		||||
 
 | 
			
		||||
@@ -116,6 +116,15 @@ export {
 | 
			
		||||
    SamplerMetrics,
 | 
			
		||||
} from './types';
 | 
			
		||||
export { affiliateFeeUtils } from './utils/affiliate_fee_utils';
 | 
			
		||||
export {
 | 
			
		||||
    IRfqClient,
 | 
			
		||||
    RfqClientV1Price,
 | 
			
		||||
    RfqClientV1PriceRequest,
 | 
			
		||||
    RfqClientV1PriceResponse,
 | 
			
		||||
    RfqClientV1Quote,
 | 
			
		||||
    RfqClientV1QuoteRequest,
 | 
			
		||||
    RfqClientV1QuoteResponse,
 | 
			
		||||
} from './utils/irfq_client';
 | 
			
		||||
export {
 | 
			
		||||
    DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID,
 | 
			
		||||
    DEFAULT_GAS_SCHEDULE,
 | 
			
		||||
@@ -144,7 +153,6 @@ export {
 | 
			
		||||
    Fill,
 | 
			
		||||
    FillData,
 | 
			
		||||
    GetMarketOrdersRfqOpts,
 | 
			
		||||
    KyberFillData,
 | 
			
		||||
    LiquidityProviderFillData,
 | 
			
		||||
    LiquidityProviderRegistry,
 | 
			
		||||
    MarketDepth,
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,7 @@ import {
 | 
			
		||||
    FinalUniswapV3FillData,
 | 
			
		||||
    LiquidityProviderFillData,
 | 
			
		||||
    MooniswapFillData,
 | 
			
		||||
    NativeRfqOrderFillData,
 | 
			
		||||
    OptimizedMarketBridgeOrder,
 | 
			
		||||
    OptimizedMarketOrder,
 | 
			
		||||
    UniswapV2FillData,
 | 
			
		||||
@@ -60,6 +61,7 @@ import {
 | 
			
		||||
    isDirectSwapCompatible,
 | 
			
		||||
    isMultiplexBatchFillCompatible,
 | 
			
		||||
    isMultiplexMultiHopFillCompatible,
 | 
			
		||||
    requiresTransformERC20,
 | 
			
		||||
} from './quote_consumer_utils';
 | 
			
		||||
 | 
			
		||||
// tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
@@ -73,9 +75,7 @@ const PANCAKE_SWAP_FORKS = [
 | 
			
		||||
    ERC20BridgeSource.BakerySwap,
 | 
			
		||||
    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
    ERC20BridgeSource.ApeSwap,
 | 
			
		||||
    ERC20BridgeSource.CafeSwap,
 | 
			
		||||
    ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
    ERC20BridgeSource.JulSwap,
 | 
			
		||||
];
 | 
			
		||||
const FAKE_PROVIDER: any = {
 | 
			
		||||
    sendAsync(): void {
 | 
			
		||||
@@ -220,9 +220,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
                ERC20BridgeSource.BakerySwap,
 | 
			
		||||
                ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                ERC20BridgeSource.ApeSwap,
 | 
			
		||||
                ERC20BridgeSource.CafeSwap,
 | 
			
		||||
                ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
                ERC20BridgeSource.JulSwap,
 | 
			
		||||
            ])
 | 
			
		||||
        ) {
 | 
			
		||||
            const source = slippedOrders[0].source;
 | 
			
		||||
@@ -278,7 +276,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
 | 
			
		||||
        if (
 | 
			
		||||
            this.chainId === ChainId.Mainnet &&
 | 
			
		||||
            isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve, ERC20BridgeSource.Swerve]) &&
 | 
			
		||||
            isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve]) &&
 | 
			
		||||
            // 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
 | 
			
		||||
@@ -333,6 +331,49 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // RFQT VIP
 | 
			
		||||
        if (
 | 
			
		||||
            [ChainId.Mainnet, ChainId.Polygon].includes(this.chainId) &&
 | 
			
		||||
            !isToETH &&
 | 
			
		||||
            !isFromETH &&
 | 
			
		||||
            quote.orders.every(o => o.type === FillQuoteTransformerOrderType.Rfq) &&
 | 
			
		||||
            !requiresTransformERC20(optsWithDefaults)
 | 
			
		||||
        ) {
 | 
			
		||||
            const rfqOrdersData = quote.orders.map(o => o.fillData as NativeRfqOrderFillData);
 | 
			
		||||
            const fillAmountPerOrder = (() => {
 | 
			
		||||
                // Don't think order taker amounts are clipped to actual sell amount
 | 
			
		||||
                // (the last one might be too large) so figure them out manually.
 | 
			
		||||
                let remaining = sellAmount;
 | 
			
		||||
                const fillAmounts = [];
 | 
			
		||||
                for (const o of quote.orders) {
 | 
			
		||||
                    const fillAmount = BigNumber.min(o.takerAmount, remaining);
 | 
			
		||||
                    fillAmounts.push(fillAmount);
 | 
			
		||||
                    remaining = remaining.minus(fillAmount);
 | 
			
		||||
                }
 | 
			
		||||
                return fillAmounts;
 | 
			
		||||
            })();
 | 
			
		||||
            const callData =
 | 
			
		||||
                quote.orders.length === 1
 | 
			
		||||
                    ? this._exchangeProxy
 | 
			
		||||
                          .fillRfqOrder(rfqOrdersData[0].order, rfqOrdersData[0].signature, fillAmountPerOrder[0])
 | 
			
		||||
                          .getABIEncodedTransactionData()
 | 
			
		||||
                    : this._exchangeProxy
 | 
			
		||||
                          .batchFillRfqOrders(
 | 
			
		||||
                              rfqOrdersData.map(d => d.order),
 | 
			
		||||
                              rfqOrdersData.map(d => d.signature),
 | 
			
		||||
                              fillAmountPerOrder,
 | 
			
		||||
                              true,
 | 
			
		||||
                          )
 | 
			
		||||
                          .getABIEncodedTransactionData();
 | 
			
		||||
            return {
 | 
			
		||||
                calldataHexString: callData,
 | 
			
		||||
                ethAmount: ZERO_AMOUNT,
 | 
			
		||||
                toAddress: this._exchangeProxy.address,
 | 
			
		||||
                allowanceTarget: this._exchangeProxy.address,
 | 
			
		||||
                gasOverhead: ZERO_AMOUNT,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
 | 
			
		||||
            return {
 | 
			
		||||
                calldataHexString: this._encodeMultiplexBatchFillCalldata(
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ import {
 | 
			
		||||
    SwapQuoterRfqOpts,
 | 
			
		||||
} from './types';
 | 
			
		||||
import { assert } from './utils/assert';
 | 
			
		||||
import { IRfqClient } from './utils/irfq_client';
 | 
			
		||||
import { MarketOperationUtils } from './utils/market_operation_utils';
 | 
			
		||||
import { BancorService } from './utils/market_operation_utils/bancor_service';
 | 
			
		||||
import { SAMPLER_ADDRESS, SOURCE_FLAGS, ZERO_AMOUNT } from './utils/market_operation_utils/constants';
 | 
			
		||||
@@ -327,6 +328,7 @@ export class SwapQuoter {
 | 
			
		||||
        assetFillAmount: BigNumber,
 | 
			
		||||
        marketOperation: MarketOperation,
 | 
			
		||||
        options: Partial<SwapQuoteRequestOpts>,
 | 
			
		||||
        rfqClient?: IRfqClient | undefined,
 | 
			
		||||
    ): Promise<SwapQuote> {
 | 
			
		||||
        assert.isETHAddressHex('makerToken', makerToken);
 | 
			
		||||
        assert.isETHAddressHex('takerToken', takerToken);
 | 
			
		||||
@@ -381,6 +383,7 @@ export class SwapQuoter {
 | 
			
		||||
                this.expiryBufferMs,
 | 
			
		||||
                rfqtOptions?.metricsProxy,
 | 
			
		||||
            );
 | 
			
		||||
            calcOpts.rfqt.rfqClient = rfqClient;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const result: OptimizerResultWithReport = await this._marketOperationUtils.getOptimizerResultAsync(
 | 
			
		||||
@@ -519,7 +522,7 @@ function createSwapQuote(
 | 
			
		||||
        : calculateQuoteInfo(optimizedOrders, operation, assetFillAmount, gasPrice, gasSchedule, slippage);
 | 
			
		||||
 | 
			
		||||
    // Put together the swap quote
 | 
			
		||||
    const { makerTokenDecimals, takerTokenDecimals } = optimizerResult.marketSideLiquidity;
 | 
			
		||||
    const { makerTokenDecimals, takerTokenDecimals, blockNumber } = optimizerResult.marketSideLiquidity;
 | 
			
		||||
    const swapQuote = {
 | 
			
		||||
        makerToken,
 | 
			
		||||
        takerToken,
 | 
			
		||||
@@ -536,6 +539,7 @@ function createSwapQuote(
 | 
			
		||||
        extendedQuoteReportSources,
 | 
			
		||||
        isTwoHop,
 | 
			
		||||
        priceComparisonsReport,
 | 
			
		||||
        blockNumber,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (operation === MarketOperation.Buy) {
 | 
			
		||||
 
 | 
			
		||||
@@ -179,6 +179,7 @@ export interface SwapQuoteBase {
 | 
			
		||||
    takerTokenDecimals: number;
 | 
			
		||||
    takerAmountPerEth: BigNumber;
 | 
			
		||||
    makerAmountPerEth: BigNumber;
 | 
			
		||||
    blockNumber: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,10 @@ import {
 | 
			
		||||
 | 
			
		||||
const SUCCESS_CODE = 201;
 | 
			
		||||
 | 
			
		||||
function getAltMarketInfo(
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the AltOffering if it exists for a given pair
 | 
			
		||||
 */
 | 
			
		||||
export function getAltMarketInfo(
 | 
			
		||||
    offerings: AltOffering[],
 | 
			
		||||
    buyTokenAddress: string,
 | 
			
		||||
    sellTokenAddress: string,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								packages/asset-swapper/src/utils/irfq_client.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								packages/asset-swapper/src/utils/irfq_client.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
import { RfqOrder, Signature } from '@0x/protocol-utils';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { AltRfqMakerAssetOfferings } from '../types';
 | 
			
		||||
 | 
			
		||||
export interface RfqClientV1PriceRequest {
 | 
			
		||||
    altRfqAssetOfferings: AltRfqMakerAssetOfferings | undefined;
 | 
			
		||||
    assetFillAmount: BigNumber;
 | 
			
		||||
    chainId: number;
 | 
			
		||||
    comparisonPrice: BigNumber | undefined;
 | 
			
		||||
    integratorId: string;
 | 
			
		||||
    intentOnFilling: boolean;
 | 
			
		||||
    makerToken: string;
 | 
			
		||||
    marketOperation: 'Sell' | 'Buy';
 | 
			
		||||
    takerAddress: string;
 | 
			
		||||
    takerToken: string;
 | 
			
		||||
    txOrigin: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface RfqClientV1QuoteRequest extends RfqClientV1PriceRequest {}
 | 
			
		||||
 | 
			
		||||
export interface RfqClientV1Price {
 | 
			
		||||
    expiry: BigNumber;
 | 
			
		||||
    kind: 'rfq' | 'otc';
 | 
			
		||||
    makerAmount: BigNumber;
 | 
			
		||||
    makerToken: string;
 | 
			
		||||
    makerUri: string;
 | 
			
		||||
    takerAmount: BigNumber;
 | 
			
		||||
    takerToken: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface RfqClientV1PriceResponse {
 | 
			
		||||
    prices: RfqClientV1Price[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface RfqClientV1Quote {
 | 
			
		||||
    makerUri: string;
 | 
			
		||||
    order: RfqOrder;
 | 
			
		||||
    signature: Signature;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface RfqClientV1QuoteResponse {
 | 
			
		||||
    quotes: RfqClientV1Quote[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * IRfqClient is an interface that defines how to connect with an Rfq system.
 | 
			
		||||
 */
 | 
			
		||||
export interface IRfqClient {
 | 
			
		||||
    /**
 | 
			
		||||
     * Fetches a list of "indicative quotes" or prices from a remote Rfq server
 | 
			
		||||
     */
 | 
			
		||||
    getV1PricesAsync(request: RfqClientV1PriceRequest): Promise<RfqClientV1PriceResponse>;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Fetches a list of "firm quotes" or signed quotes from a remote Rfq server.
 | 
			
		||||
     */
 | 
			
		||||
    getV1QuotesAsync(request: RfqClientV1QuoteRequest): Promise<RfqClientV1QuoteResponse>;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
import { ChainId } from '@0x/contract-addresses';
 | 
			
		||||
import { BigNumber, NULL_BYTES } from '@0x/utils';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
    ACRYPTOS_BSC_INFOS,
 | 
			
		||||
    APESWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    BAKERYSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    BELT_BSC_INFOS,
 | 
			
		||||
    CAFESWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    BISWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    CHEESESWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    COMETHSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    COMPONENT_POOLS_BY_CHAIN_ID,
 | 
			
		||||
@@ -25,12 +25,11 @@ import {
 | 
			
		||||
    FIREBIRDONESWAP_BSC_INFOS,
 | 
			
		||||
    FIREBIRDONESWAP_POLYGON_INFOS,
 | 
			
		||||
    IRONSWAP_POLYGON_INFOS,
 | 
			
		||||
    JETSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    JULSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    KYBER_BANNED_RESERVES,
 | 
			
		||||
    KYBER_BRIDGED_LIQUIDITY_PREFIX,
 | 
			
		||||
    KNIGHTSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    MAX_DODOV2_POOLS_QUERIED,
 | 
			
		||||
    MAX_KYBER_RESERVES_QUERIED,
 | 
			
		||||
    MDEX_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    MESHSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    MOBIUSMONEY_CELO_INFOS,
 | 
			
		||||
    MORPHEUSSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    MSTABLE_POOLS_BY_CHAIN_ID,
 | 
			
		||||
    NERVE_BSC_INFOS,
 | 
			
		||||
@@ -38,18 +37,16 @@ import {
 | 
			
		||||
    PANCAKESWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    PANCAKESWAPV2_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    PANGOLIN_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    POLYDEX_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    PLATYPUS_AVALANCHE_INFOS,
 | 
			
		||||
    QUICKSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SADDLE_MAINNET_INFOS,
 | 
			
		||||
    SHELL_POOLS_BY_CHAIN_ID,
 | 
			
		||||
    SHIBASWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SMOOTHY_BSC_INFOS,
 | 
			
		||||
    SMOOTHY_MAINNET_INFOS,
 | 
			
		||||
    SNOWSWAP_MAINNET_INFOS,
 | 
			
		||||
    SPIRITSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SPOOKYSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SUSHISWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SWERVE_MAINNET_INFOS,
 | 
			
		||||
    SYNAPSE_AVALANCHE_INFOS,
 | 
			
		||||
    SYNAPSE_BSC_INFOS,
 | 
			
		||||
    SYNAPSE_FANTOM_INFOS,
 | 
			
		||||
@@ -61,35 +58,15 @@ import {
 | 
			
		||||
    UNISWAPV2_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    WAULTSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    XSIGMA_MAINNET_INFOS,
 | 
			
		||||
    YOSHI_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
} from './constants';
 | 
			
		||||
import { CurveInfo, ERC20BridgeSource } from './types';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Filter Kyber reserves which should not be used (0xbb bridged reserves)
 | 
			
		||||
 * @param reserveId Kyber reserveId
 | 
			
		||||
 */
 | 
			
		||||
export function isAllowedKyberReserveId(reserveId: string): boolean {
 | 
			
		||||
    return (
 | 
			
		||||
        reserveId !== NULL_BYTES &&
 | 
			
		||||
        !reserveId.startsWith(KYBER_BRIDGED_LIQUIDITY_PREFIX) &&
 | 
			
		||||
        !KYBER_BANNED_RESERVES.includes(reserveId)
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
import { CurveInfo, ERC20BridgeSource, PlatypusInfo } from './types';
 | 
			
		||||
 | 
			
		||||
// tslint:disable-next-line: completed-docs ban-types
 | 
			
		||||
export function isValidAddress(address: string | String): address is string {
 | 
			
		||||
    return (typeof address === 'string' || address instanceof String) && address.toString() !== NULL_ADDRESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the offsets to be used to discover Kyber reserves
 | 
			
		||||
 */
 | 
			
		||||
export function getKyberOffsets(): BigNumber[] {
 | 
			
		||||
    return Array(MAX_KYBER_RESERVES_QUERIED)
 | 
			
		||||
        .fill(0)
 | 
			
		||||
        .map((_v, i) => new BigNumber(i));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tslint:disable completed-docs
 | 
			
		||||
export function getDodoV2Offsets(): BigNumber[] {
 | 
			
		||||
    return Array(MAX_DODOV2_POOLS_QUERIED)
 | 
			
		||||
@@ -224,32 +201,6 @@ export function getCurveV2InfosForPair(chainId: ChainId, takerToken: string, mak
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getSwerveInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
 | 
			
		||||
    if (chainId !== ChainId.Mainnet) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
    return Object.values(SWERVE_MAINNET_INFOS).filter(c =>
 | 
			
		||||
        [makerToken, takerToken].every(
 | 
			
		||||
            t =>
 | 
			
		||||
                (c.tokens.includes(t) && c.metaTokens === undefined) ||
 | 
			
		||||
                (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getSnowSwapInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
 | 
			
		||||
    if (chainId !== ChainId.Mainnet) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
    return Object.values(SNOWSWAP_MAINNET_INFOS).filter(c =>
 | 
			
		||||
        [makerToken, takerToken].every(
 | 
			
		||||
            t =>
 | 
			
		||||
                (c.tokens.includes(t) && c.metaTokens === undefined) ||
 | 
			
		||||
                (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getNerveInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
 | 
			
		||||
    if (chainId !== ChainId.BSC) {
 | 
			
		||||
        return [];
 | 
			
		||||
@@ -449,6 +400,27 @@ export function getAcryptosInfosForPair(chainId: ChainId, takerToken: string, ma
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
export function getMobiusMoneyInfoForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
 | 
			
		||||
    if (chainId !== ChainId.Celo) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
    return Object.values(MOBIUSMONEY_CELO_INFOS).filter(c =>
 | 
			
		||||
        [makerToken, takerToken].every(
 | 
			
		||||
            t =>
 | 
			
		||||
                (c.tokens.includes(t) && c.metaTokens === undefined) ||
 | 
			
		||||
                (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
 | 
			
		||||
        ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getPlatypusInfoForPair(chainId: ChainId, takerToken: string, makerToken: string): PlatypusInfo[] {
 | 
			
		||||
    if (chainId !== ChainId.Avalanche) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
    return Object.values(PLATYPUS_AVALANCHE_INFOS).filter(c =>
 | 
			
		||||
        [makerToken, takerToken].every(t => c.tokens.includes(t)),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getShellLikeInfosForPair(
 | 
			
		||||
    chainId: ChainId,
 | 
			
		||||
@@ -480,8 +452,6 @@ export function getCurveLikeInfosForPair(
 | 
			
		||||
    source:
 | 
			
		||||
        | ERC20BridgeSource.Curve
 | 
			
		||||
        | ERC20BridgeSource.CurveV2
 | 
			
		||||
        | ERC20BridgeSource.Swerve
 | 
			
		||||
        | ERC20BridgeSource.SnowSwap
 | 
			
		||||
        | ERC20BridgeSource.Nerve
 | 
			
		||||
        | ERC20BridgeSource.Synapse
 | 
			
		||||
        | ERC20BridgeSource.Belt
 | 
			
		||||
@@ -491,7 +461,8 @@ export function getCurveLikeInfosForPair(
 | 
			
		||||
        | ERC20BridgeSource.IronSwap
 | 
			
		||||
        | ERC20BridgeSource.XSigma
 | 
			
		||||
        | ERC20BridgeSource.FirebirdOneSwap
 | 
			
		||||
        | ERC20BridgeSource.ACryptos,
 | 
			
		||||
        | ERC20BridgeSource.ACryptos
 | 
			
		||||
        | ERC20BridgeSource.MobiusMoney,
 | 
			
		||||
): CurveDetailedInfo[] {
 | 
			
		||||
    let pools: CurveInfo[] = [];
 | 
			
		||||
    switch (source) {
 | 
			
		||||
@@ -501,12 +472,6 @@ export function getCurveLikeInfosForPair(
 | 
			
		||||
        case ERC20BridgeSource.CurveV2:
 | 
			
		||||
            pools = getCurveV2InfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Swerve:
 | 
			
		||||
            pools = getSwerveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.SnowSwap:
 | 
			
		||||
            pools = getSnowSwapInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Nerve:
 | 
			
		||||
            pools = getNerveInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
@@ -537,6 +502,9 @@ export function getCurveLikeInfosForPair(
 | 
			
		||||
        case ERC20BridgeSource.ACryptos:
 | 
			
		||||
            pools = getAcryptosInfosForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.MobiusMoney:
 | 
			
		||||
            pools = getMobiusMoneyInfoForPair(chainId, takerToken, makerToken);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(`Unknown Curve like source ${source}`);
 | 
			
		||||
    }
 | 
			
		||||
@@ -557,22 +525,23 @@ export function uniswapV2LikeRouterAddress(
 | 
			
		||||
        | ERC20BridgeSource.PancakeSwapV2
 | 
			
		||||
        | ERC20BridgeSource.BakerySwap
 | 
			
		||||
        | ERC20BridgeSource.ApeSwap
 | 
			
		||||
        | ERC20BridgeSource.CafeSwap
 | 
			
		||||
        | ERC20BridgeSource.CheeseSwap
 | 
			
		||||
        | ERC20BridgeSource.JulSwap
 | 
			
		||||
        | ERC20BridgeSource.QuickSwap
 | 
			
		||||
        | ERC20BridgeSource.ComethSwap
 | 
			
		||||
        | ERC20BridgeSource.Dfyn
 | 
			
		||||
        | ERC20BridgeSource.WaultSwap
 | 
			
		||||
        | ERC20BridgeSource.Polydex
 | 
			
		||||
        | ERC20BridgeSource.ShibaSwap
 | 
			
		||||
        | ERC20BridgeSource.JetSwap
 | 
			
		||||
        | ERC20BridgeSource.TraderJoe
 | 
			
		||||
        | ERC20BridgeSource.Pangolin
 | 
			
		||||
        | ERC20BridgeSource.UbeSwap
 | 
			
		||||
        | ERC20BridgeSource.MorpheusSwap
 | 
			
		||||
        | ERC20BridgeSource.SpookySwap
 | 
			
		||||
        | ERC20BridgeSource.SpiritSwap,
 | 
			
		||||
        | ERC20BridgeSource.SpiritSwap
 | 
			
		||||
        | ERC20BridgeSource.BiSwap
 | 
			
		||||
        | ERC20BridgeSource.Yoshi
 | 
			
		||||
        | ERC20BridgeSource.MDex
 | 
			
		||||
        | ERC20BridgeSource.KnightSwap
 | 
			
		||||
        | ERC20BridgeSource.MeshSwap,
 | 
			
		||||
): string {
 | 
			
		||||
    switch (source) {
 | 
			
		||||
        case ERC20BridgeSource.UniswapV2:
 | 
			
		||||
@@ -589,12 +558,8 @@ export function uniswapV2LikeRouterAddress(
 | 
			
		||||
            return BAKERYSWAP_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];
 | 
			
		||||
        case ERC20BridgeSource.QuickSwap:
 | 
			
		||||
            return QUICKSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.ComethSwap:
 | 
			
		||||
@@ -603,12 +568,8 @@ export function uniswapV2LikeRouterAddress(
 | 
			
		||||
            return DFYN_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.WaultSwap:
 | 
			
		||||
            return WAULTSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.Polydex:
 | 
			
		||||
            return POLYDEX_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.ShibaSwap:
 | 
			
		||||
            return SHIBASWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.JetSwap:
 | 
			
		||||
            return JETSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.Pangolin:
 | 
			
		||||
            return PANGOLIN_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.TraderJoe:
 | 
			
		||||
@@ -621,6 +582,16 @@ export function uniswapV2LikeRouterAddress(
 | 
			
		||||
            return SPOOKYSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.SpiritSwap:
 | 
			
		||||
            return SPIRITSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.BiSwap:
 | 
			
		||||
            return BISWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.Yoshi:
 | 
			
		||||
            return YOSHI_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.MeshSwap:
 | 
			
		||||
            return MESHSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.MDex:
 | 
			
		||||
            return MDEX_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        case ERC20BridgeSource.KnightSwap:
 | 
			
		||||
            return KNIGHTSWAP_ROUTER_BY_CHAIN_ID[chainId];
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(`Unknown UniswapV2 like source ${source}`);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import { TokenAdjacencyGraphBuilder } from '../token_adjacency_graph_builder';
 | 
			
		||||
import { SourceFilters } from './source_filters';
 | 
			
		||||
import {
 | 
			
		||||
    AaveV2FillData,
 | 
			
		||||
    BalancerV2BatchSwapFillData,
 | 
			
		||||
    BancorFillData,
 | 
			
		||||
    CompoundFillData,
 | 
			
		||||
    CurveFillData,
 | 
			
		||||
@@ -21,12 +22,13 @@ import {
 | 
			
		||||
    GeistFillData,
 | 
			
		||||
    GetMarketOrdersOpts,
 | 
			
		||||
    isFinalUniswapV3FillData,
 | 
			
		||||
    KyberSamplerOpts,
 | 
			
		||||
    LidoFillData,
 | 
			
		||||
    LidoInfo,
 | 
			
		||||
    LiquidityProviderFillData,
 | 
			
		||||
    LiquidityProviderRegistry,
 | 
			
		||||
    MakerPsmFillData,
 | 
			
		||||
    MultiHopFillData,
 | 
			
		||||
    PlatypusInfo,
 | 
			
		||||
    PsmInfo,
 | 
			
		||||
    TokenAdjacencyGraph,
 | 
			
		||||
    UniswapV2FillData,
 | 
			
		||||
@@ -78,16 +80,13 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Native,
 | 
			
		||||
            ERC20BridgeSource.Uniswap,
 | 
			
		||||
            ERC20BridgeSource.UniswapV2,
 | 
			
		||||
            ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.Balancer,
 | 
			
		||||
            ERC20BridgeSource.BalancerV2,
 | 
			
		||||
            ERC20BridgeSource.Bancor,
 | 
			
		||||
            ERC20BridgeSource.BancorV3,
 | 
			
		||||
            ERC20BridgeSource.MStable,
 | 
			
		||||
            ERC20BridgeSource.Mooniswap,
 | 
			
		||||
            ERC20BridgeSource.Swerve,
 | 
			
		||||
            ERC20BridgeSource.SnowSwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Shell,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
@@ -96,7 +95,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Cream,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.CryptoCom,
 | 
			
		||||
            ERC20BridgeSource.Linkswap,
 | 
			
		||||
            ERC20BridgeSource.Lido,
 | 
			
		||||
            ERC20BridgeSource.MakerPsm,
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
@@ -113,7 +111,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            // ERC20BridgeSource.Compound,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Ropsten]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
            ERC20BridgeSource.Native,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Uniswap,
 | 
			
		||||
@@ -140,15 +137,15 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.CafeSwap,
 | 
			
		||||
            ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
            ERC20BridgeSource.JulSwap,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.WaultSwap,
 | 
			
		||||
            ERC20BridgeSource.FirebirdOneSwap,
 | 
			
		||||
            ERC20BridgeSource.JetSwap,
 | 
			
		||||
            ERC20BridgeSource.ACryptos,
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.BiSwap,
 | 
			
		||||
            ERC20BridgeSource.MDex,
 | 
			
		||||
            ERC20BridgeSource.KnightSwap,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Polygon]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
@@ -161,18 +158,17 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Dodo,
 | 
			
		||||
            ERC20BridgeSource.CurveV2,
 | 
			
		||||
            ERC20BridgeSource.WaultSwap,
 | 
			
		||||
            ERC20BridgeSource.Polydex,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.FirebirdOneSwap,
 | 
			
		||||
            ERC20BridgeSource.BalancerV2,
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.JetSwap,
 | 
			
		||||
            ERC20BridgeSource.IronSwap,
 | 
			
		||||
            ERC20BridgeSource.AaveV2,
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.MeshSwap,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Avalanche]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
@@ -184,6 +180,8 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.AaveV2,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.GMX,
 | 
			
		||||
            ERC20BridgeSource.Platypus,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Fantom]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
@@ -191,17 +189,18 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.CurveV2,
 | 
			
		||||
            ERC20BridgeSource.Geist,
 | 
			
		||||
            ERC20BridgeSource.JetSwap,
 | 
			
		||||
            ERC20BridgeSource.MorpheusSwap,
 | 
			
		||||
            ERC20BridgeSource.SpiritSwap,
 | 
			
		||||
            ERC20BridgeSource.SpookySwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.Yoshi,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Celo]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.UbeSwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.MobiusMoney,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Optimism]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
@@ -209,6 +208,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.CurveV2,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.Velodrome,
 | 
			
		||||
        ]),
 | 
			
		||||
    },
 | 
			
		||||
    new SourceFilters([]),
 | 
			
		||||
@@ -223,17 +223,14 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Native,
 | 
			
		||||
            ERC20BridgeSource.Uniswap,
 | 
			
		||||
            ERC20BridgeSource.UniswapV2,
 | 
			
		||||
            ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.Balancer,
 | 
			
		||||
            ERC20BridgeSource.BalancerV2,
 | 
			
		||||
            // ERC20BridgeSource.Bancor, // FIXME: Bancor Buys not implemented in Sampler
 | 
			
		||||
            ERC20BridgeSource.BancorV3,
 | 
			
		||||
            ERC20BridgeSource.MStable,
 | 
			
		||||
            ERC20BridgeSource.Mooniswap,
 | 
			
		||||
            ERC20BridgeSource.Shell,
 | 
			
		||||
            ERC20BridgeSource.Swerve,
 | 
			
		||||
            ERC20BridgeSource.SnowSwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.Dodo,
 | 
			
		||||
@@ -242,7 +239,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Lido,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.CryptoCom,
 | 
			
		||||
            ERC20BridgeSource.Linkswap,
 | 
			
		||||
            ERC20BridgeSource.MakerPsm,
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
@@ -258,7 +254,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            // ERC20BridgeSource.Compound,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Ropsten]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.Kyber,
 | 
			
		||||
            ERC20BridgeSource.Native,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Uniswap,
 | 
			
		||||
@@ -279,21 +274,21 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Mooniswap,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.Nerve,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwap,
 | 
			
		||||
            ERC20BridgeSource.PancakeSwapV2,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Smoothy,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.CafeSwap,
 | 
			
		||||
            ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
            ERC20BridgeSource.JulSwap,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.WaultSwap,
 | 
			
		||||
            ERC20BridgeSource.FirebirdOneSwap,
 | 
			
		||||
            ERC20BridgeSource.JetSwap,
 | 
			
		||||
            ERC20BridgeSource.ACryptos,
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.BiSwap,
 | 
			
		||||
            ERC20BridgeSource.MDex,
 | 
			
		||||
            ERC20BridgeSource.KnightSwap,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Polygon]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
@@ -306,18 +301,17 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Dodo,
 | 
			
		||||
            ERC20BridgeSource.CurveV2,
 | 
			
		||||
            ERC20BridgeSource.WaultSwap,
 | 
			
		||||
            ERC20BridgeSource.Polydex,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.FirebirdOneSwap,
 | 
			
		||||
            ERC20BridgeSource.BalancerV2,
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.JetSwap,
 | 
			
		||||
            ERC20BridgeSource.IronSwap,
 | 
			
		||||
            ERC20BridgeSource.AaveV2,
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.MeshSwap,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Avalanche]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
@@ -329,6 +323,8 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.KyberDmm,
 | 
			
		||||
            ERC20BridgeSource.AaveV2,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.GMX,
 | 
			
		||||
            ERC20BridgeSource.Platypus,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Fantom]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
@@ -336,17 +332,18 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.CurveV2,
 | 
			
		||||
            ERC20BridgeSource.Geist,
 | 
			
		||||
            ERC20BridgeSource.JetSwap,
 | 
			
		||||
            ERC20BridgeSource.MorpheusSwap,
 | 
			
		||||
            ERC20BridgeSource.SpiritSwap,
 | 
			
		||||
            ERC20BridgeSource.SpookySwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.Synapse,
 | 
			
		||||
            ERC20BridgeSource.Yoshi,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Celo]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.UbeSwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.MobiusMoney,
 | 
			
		||||
        ]),
 | 
			
		||||
        [ChainId.Optimism]: new SourceFilters([
 | 
			
		||||
            ERC20BridgeSource.UniswapV3,
 | 
			
		||||
@@ -354,6 +351,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
 | 
			
		||||
            ERC20BridgeSource.Curve,
 | 
			
		||||
            ERC20BridgeSource.CurveV2,
 | 
			
		||||
            ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ERC20BridgeSource.Velodrome,
 | 
			
		||||
        ]),
 | 
			
		||||
    },
 | 
			
		||||
    new SourceFilters([]),
 | 
			
		||||
@@ -433,6 +431,7 @@ export const MAINNET_TOKENS = {
 | 
			
		||||
    RenBTC: '0xeb4c2781e4eba804ce9a9803c67d0893436bb27d',
 | 
			
		||||
    sBTC: '0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6',
 | 
			
		||||
    tBTC: '0x8daebade922df735c38c80c7ebd708af50815faa',
 | 
			
		||||
    tBTCv2: '0x18084fbA666a33d37592fA2633fD49a74DD93a88',
 | 
			
		||||
    hBTC: '0x0316eb71485b0ab14103307bf65a021042c6d380',
 | 
			
		||||
    pBTC: '0x5228a22e72ccc52d415ecfd199f99d0665e7733b',
 | 
			
		||||
    bBTC: '0x9be89d2a4cd102d8fecc6bf9da793be995c22541',
 | 
			
		||||
@@ -448,6 +447,7 @@ export const MAINNET_TOKENS = {
 | 
			
		||||
    sEUR: '0xd71ecff9342a5ced620049e616c5035f1db98620',
 | 
			
		||||
    sETH: '0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb',
 | 
			
		||||
    stETH: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84',
 | 
			
		||||
    wstETH: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
 | 
			
		||||
    LINK: '0x514910771af9ca656af840dff83e8264ecf986ca',
 | 
			
		||||
    MANA: '0x0f5d2fb29fb7d3cfee444a200298f468908cc942',
 | 
			
		||||
    KNC: '0xdefa4e8a7bcba345f687a2f1456f5edd9ce97202',
 | 
			
		||||
@@ -475,10 +475,13 @@ export const MAINNET_TOKENS = {
 | 
			
		||||
    alUSD: '0xbc6da0fe9ad5f3b0d58160288917aa56653660e9',
 | 
			
		||||
    // Frax ecosystem
 | 
			
		||||
    FRAX: '0x853d955acef822db058eb8505911ed77f175b99e',
 | 
			
		||||
    cvxFXS: '0xfeef77d3f69374f66429c91d732a244f074bdf74',
 | 
			
		||||
    FXS: '0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0',
 | 
			
		||||
    OHM: '0x383518188c0c6d7730d91b2c03a03c837814a899',
 | 
			
		||||
    OHMV2: '0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5',
 | 
			
		||||
    BTRFLY: '0xc0d4ceb216b3ba9c3701b291766fdcba977cec3a',
 | 
			
		||||
    // Stargate
 | 
			
		||||
    STG: '0xaf5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6',
 | 
			
		||||
    //
 | 
			
		||||
    LUSD: '0x5f98805a4e8be255a32880fdec7f6728c6568ba0',
 | 
			
		||||
    // Fei Ecosystem
 | 
			
		||||
@@ -500,6 +503,7 @@ export const MAINNET_TOKENS = {
 | 
			
		||||
    OUSD: '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86',
 | 
			
		||||
    agEUR: '0x1a7e4e63778b4f12a199c062f3efdd288afcbce8',
 | 
			
		||||
    ibEUR: '0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27',
 | 
			
		||||
    YFI: '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const BSC_TOKENS = {
 | 
			
		||||
@@ -517,6 +521,7 @@ export const BSC_TOKENS = {
 | 
			
		||||
    renBTC: '0xfce146bf3146100cfe5db4129cf6c82b0ef4ad8c',
 | 
			
		||||
    pBTC: '0xed28a457a5a76596ac48d87c0f577020f6ea1c4c',
 | 
			
		||||
    nUSD: '0x23b891e5c62e0955ae2bd185990103928ab817b3',
 | 
			
		||||
    BSW: '0x965F527D9159dCe6288a2219DB51fc6Eef120dD1',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const POLYGON_TOKENS = {
 | 
			
		||||
@@ -535,6 +540,7 @@ export const POLYGON_TOKENS = {
 | 
			
		||||
    BANANA: '0x5d47baba0d66083c52009271faf3f50dcc01023c',
 | 
			
		||||
    WEXPOLY: '0x4c4bf319237d98a30a929a96112effa8da3510eb',
 | 
			
		||||
    nUSD: '0xb6c473756050de474286bed418b77aeac39b02af',
 | 
			
		||||
    ANY: '0x6aB6d61428fde76768D7b45D8BFeec19c6eF91A8',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const AVALANCHE_TOKENS = {
 | 
			
		||||
@@ -544,8 +550,10 @@ export const AVALANCHE_TOKENS = {
 | 
			
		||||
    DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70',
 | 
			
		||||
    // bridged USDC
 | 
			
		||||
    USDC: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664',
 | 
			
		||||
    // native USDC on Avalanche
 | 
			
		||||
    // native USDC on Avalanche usdc.e
 | 
			
		||||
    nUSDC: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
 | 
			
		||||
    // usdt.e
 | 
			
		||||
    USDt: '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7',
 | 
			
		||||
    USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118',
 | 
			
		||||
    aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a',
 | 
			
		||||
    aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857',
 | 
			
		||||
@@ -554,6 +562,11 @@ export const AVALANCHE_TOKENS = {
 | 
			
		||||
    nUSD: '0xcfc37a6ab183dd4aed08c204d1c2773c0b1bdf46',
 | 
			
		||||
    aWETH: '0x53f7c5869a859f0aec3d334ee8b4cf01e3492f21',
 | 
			
		||||
    MIM: '0x130966628846bfd36ff31a822705796e8cb8c18d',
 | 
			
		||||
    MAG: '0x1d60109178C48E4A937D8AB71699D8eBb6F7c5dE',
 | 
			
		||||
    sAVAX: '0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be',
 | 
			
		||||
    UST: '0xb599c3590f42f8f995ecfa0f85d2980b76862fc1',
 | 
			
		||||
    FRAX: '0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64',
 | 
			
		||||
    YUSD: '0x111111111111ed1d73f860f57b2798b683f2d325',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const CELO_TOKENS = {
 | 
			
		||||
@@ -561,11 +574,11 @@ export const CELO_TOKENS = {
 | 
			
		||||
    // Some of these tokens are Optics bridge? tokens which
 | 
			
		||||
    // had an issue and migrated from v1 to v2
 | 
			
		||||
    WETHv1: '0xe919f65739c26a42616b7b8eedc6b5524d1e3ac4',
 | 
			
		||||
    WETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455',
 | 
			
		||||
    oWETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455',
 | 
			
		||||
    WBTC: '0xbaab46e28388d2779e6e31fd00cf0e5ad95e327b',
 | 
			
		||||
    cUSD: '0x765de816845861e75a25fca122bb6898b8b1282a',
 | 
			
		||||
    // ??
 | 
			
		||||
    WBTCv1: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b',
 | 
			
		||||
    cBTC: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b',
 | 
			
		||||
    cETH: '0x2def4285787d58a2f811af24755a8150622f4361',
 | 
			
		||||
    UBE: '0x00be915b9dcf56a3cbe739d9b9c202ca692409ec',
 | 
			
		||||
    // Moolah
 | 
			
		||||
@@ -574,6 +587,22 @@ export const CELO_TOKENS = {
 | 
			
		||||
    mCEUR: '0xe273ad7ee11dcfaa87383ad5977ee1504ac07568',
 | 
			
		||||
    amCUSD: '0x64defa3544c695db8c535d289d843a189aa26b98',
 | 
			
		||||
    MOO: '0x17700282592d6917f6a73d0bf8accf4d578c131e',
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    wBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
 | 
			
		||||
    wETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
 | 
			
		||||
    wBTCO: '0xbe50a3013a1c94768a1abb78c3cb79ab28fc1ace',
 | 
			
		||||
    pUSDC: '0xcc82628f6a8defa1e2b0ad7ed448bef3647f7941',
 | 
			
		||||
    cUSDC: '0x2a3684e9dc20b857375ea04235f2f7edbe818fa7',
 | 
			
		||||
    cUSDC_V2: '0xef4229c8c3250c675f21bcefa42f58efbff6002a',
 | 
			
		||||
    pUSDC_V2: '0x1bfc26ce035c368503fae319cc2596716428ca44',
 | 
			
		||||
    pUSD: '0xeadf4a7168a82d30ba0619e64d5bcf5b30b45226',
 | 
			
		||||
    pCELO: '0x301a61d01a63c8d670c2b8a43f37d12ef181f997',
 | 
			
		||||
    aaUSDC: '0xb70e0a782b058bfdb0d109a3599bec1f19328e36',
 | 
			
		||||
    asUSDC: '0xcd7d7ff64746c1909e44db8e95331f9316478817',
 | 
			
		||||
    mcUSDT: '0xcfffe0c89a779c09df3df5624f54cdf7ef5fdd5d',
 | 
			
		||||
    mcUSDC: '0x93db49be12b864019da9cb147ba75cdc0506190e',
 | 
			
		||||
    DAI: '0x90ca507a5d4458a4c6c6249d186b6dcb02a5bccd',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const FANTOM_TOKENS = {
 | 
			
		||||
@@ -647,6 +676,7 @@ export const CURVE_POOLS = {
 | 
			
		||||
    ib: '0x2dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf', // iron bank
 | 
			
		||||
    link: '0xf178c0b5bb7e7abf4e12a4838c7b7c5ba2c623c0', // link
 | 
			
		||||
    btrflyweth: '0xf43b15ab692fde1f9c24a9fce700adcc809d5391', // redacted cartel
 | 
			
		||||
    stgusdc: '0x3211c6cbef1429da3d0d58494938299c92ad5860', // stargate
 | 
			
		||||
    // StableSwap "open pools" (crv.finance)
 | 
			
		||||
    TUSD: '0xecd5e75afb02efa118af914515d6521aabd189f1',
 | 
			
		||||
    STABLEx: '0x3252efd4ea2d6c78091a1f43982ee2c3659cc3d1',
 | 
			
		||||
@@ -656,6 +686,7 @@ export const CURVE_POOLS = {
 | 
			
		||||
    BUSD: '0x4807862aa8b2bf68830e4c8dc86d0e9a998e085a',
 | 
			
		||||
    DSU3CRV: '0x6ec80df362d7042c50d4469bcfbc174c9dd9109a',
 | 
			
		||||
    cvxcrv: '0x9d0464996170c6b9e75eed71c68b99ddedf279e8',
 | 
			
		||||
    cvxfxs: '0xd658a338613198204dca1143ac3f01a722b5d94a',
 | 
			
		||||
    mim: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
 | 
			
		||||
    eurt: '0xfd5db7463a3ab53fd211b4af195c5bccc1a03890',
 | 
			
		||||
    ethcrv: '0x8301ae4fc9c624d1d396cbdaa1ed877821d7c511',
 | 
			
		||||
@@ -669,6 +700,7 @@ export const CURVE_POOLS = {
 | 
			
		||||
    d3pool: '0xbaaa1f5dba42c3389bdbc2c9d2de134f5cd0dc89',
 | 
			
		||||
    triEURpool: '0xb9446c4ef5ebe66268da6700d26f96273de3d571',
 | 
			
		||||
    ibEURsEUR: '0x19b080fe1ffa0553469d20ca36219f17fcf03859',
 | 
			
		||||
    wethyfi: '0xc26b89a667578ec7b3f11b2f98d6fd15c07c54ba',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const CURVE_V2_POOLS = {
 | 
			
		||||
@@ -712,28 +744,13 @@ export const CURVE_OPTIMISM_POOLS = {
 | 
			
		||||
    tri: '0x1337bedc9d22ecbe766df105c9623922a27963ec',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const SWERVE_POOLS = {
 | 
			
		||||
    y: '0x329239599afb305da0a2ec69c58f8a6697f9f88d',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const SNOWSWAP_POOLS = {
 | 
			
		||||
    yUSD: '0xbf7ccd6c446acfcc5df023043f2167b62e81899b',
 | 
			
		||||
    yVault: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b',
 | 
			
		||||
    // 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 = {
 | 
			
		||||
    syUSD: '0xe5859f4efc09027a9b718781dcb2c6910cac6e91',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const SADDLE_POOLS = {
 | 
			
		||||
    stables: '0x3911f80530595fbd01ab1516ab61255d75aeb066',
 | 
			
		||||
    bitcoins: '0x4f6a43ad7cba042606decaca730d4ce0a57ac62e',
 | 
			
		||||
    stablesV2: '0xaCb83E0633d6605c5001e2Ab59EF3C745547C8C7',
 | 
			
		||||
    bitcoinsV2: '0xdf3309771d2BF82cb2B6C56F9f5365C8bD97c4f2',
 | 
			
		||||
    alETH: '0xa6018520eaacc06c30ff2e1b3ee2c7c22e64196a',
 | 
			
		||||
    d4: '0xc69ddcd4dfef25d8a793241834d4cc4b3668ead6',
 | 
			
		||||
};
 | 
			
		||||
@@ -796,6 +813,14 @@ export const FIREBIRDONESWAP_BSC_POOLS = {
 | 
			
		||||
export const FIREBIRDONESWAP_POLYGON_POOLS = {
 | 
			
		||||
    oneswap: '0x01c9475dbd36e46d1961572c8de24b74616bae9e',
 | 
			
		||||
};
 | 
			
		||||
export const MOBIUSMONEY_CELO_POOLS = {
 | 
			
		||||
    usdc_optics_v2: '0x9906589ea8fd27504974b7e8201df5bbde986b03',
 | 
			
		||||
    dai_optics_v2: '0xf3f65dfe0c8c8f2986da0fec159abe6fd4e700b4',
 | 
			
		||||
    weth_optics_v2: '0x74ef28d635c6c5800dd3cd62d4c4f8752daacb09',
 | 
			
		||||
    pusdc_optics_v2: '0xcce0d62ce14fb3e4363eb92db37ff3630836c252',
 | 
			
		||||
    usdc_allbridge_solana: '0x63c1914bf00a9b395a2bf89aada55a5615a3656e',
 | 
			
		||||
    usdc_poly_optics: '0xa2f0e57d4ceacf025e81c76f28b9ad6e9fbe8735',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const ACRYPTOS_POOLS = {
 | 
			
		||||
    acs4usd: '0xb3f0c9ea1f05e312093fdb031e789a756659b0ac',
 | 
			
		||||
@@ -804,6 +829,14 @@ export const ACRYPTOS_POOLS = {
 | 
			
		||||
    acs3btc: '0xbe7caa236544d1b9a0e7f91e94b9f5bfd3b5ca81',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const PLATYPUS_AVALANCHE_POOLS = {
 | 
			
		||||
    usd: '0x66357dcace80431aee0a7507e2e361b7e2402370',
 | 
			
		||||
    yusd: '0xc828d995c686aaba78a4ac89dfc8ec0ff4c5be83',
 | 
			
		||||
    frax: '0xb8e567fc23c39c94a1f6359509d7b43d1fbed824',
 | 
			
		||||
    mim: '0x30c30d826be87cd0a4b90855c2f38f7fcfe4eaa7',
 | 
			
		||||
    sAVAX: '0x4658ea7e9960d6158a261104aaa160cc953bb6ba',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: [
 | 
			
		||||
@@ -845,6 +878,7 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
 | 
			
		||||
            AVALANCHE_TOKENS.nUSD,
 | 
			
		||||
            AVALANCHE_TOKENS.nETH,
 | 
			
		||||
            AVALANCHE_TOKENS.aWETH,
 | 
			
		||||
            AVALANCHE_TOKENS.MIM,
 | 
			
		||||
        ],
 | 
			
		||||
        [ChainId.Fantom]: [
 | 
			
		||||
            FANTOM_TOKENS.WFTM,
 | 
			
		||||
@@ -855,7 +889,13 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
 | 
			
		||||
            FANTOM_TOKENS.nETH,
 | 
			
		||||
            FANTOM_TOKENS.MIM,
 | 
			
		||||
        ],
 | 
			
		||||
        [ChainId.Celo]: [CELO_TOKENS.WCELO, CELO_TOKENS.mCUSD, CELO_TOKENS.WETH, CELO_TOKENS.amCUSD, CELO_TOKENS.WBTC],
 | 
			
		||||
        [ChainId.Celo]: [
 | 
			
		||||
            CELO_TOKENS.WCELO,
 | 
			
		||||
            CELO_TOKENS.mCUSD,
 | 
			
		||||
            CELO_TOKENS.WETHv1,
 | 
			
		||||
            CELO_TOKENS.amCUSD,
 | 
			
		||||
            CELO_TOKENS.WBTC,
 | 
			
		||||
        ],
 | 
			
		||||
        [ChainId.Optimism]: [
 | 
			
		||||
            OPTIMISM_TOKENS.WETH,
 | 
			
		||||
            OPTIMISM_TOKENS.DAI,
 | 
			
		||||
@@ -880,6 +920,8 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
 | 
			
		||||
                builder.add(MAINNET_TOKENS.MIR, MAINNET_TOKENS.UST);
 | 
			
		||||
                // Convex and Curve
 | 
			
		||||
                builder.add(MAINNET_TOKENS.cvxCRV, MAINNET_TOKENS.CRV).add(MAINNET_TOKENS.CRV, MAINNET_TOKENS.cvxCRV);
 | 
			
		||||
                // Convex and FXS
 | 
			
		||||
                builder.add(MAINNET_TOKENS.cvxFXS, MAINNET_TOKENS.FXS).add(MAINNET_TOKENS.FXS, MAINNET_TOKENS.cvxFXS);
 | 
			
		||||
                // FEI TRIBE liquid in UniV2
 | 
			
		||||
                builder.add(MAINNET_TOKENS.FEI, MAINNET_TOKENS.TRIBE).add(MAINNET_TOKENS.TRIBE, MAINNET_TOKENS.FEI);
 | 
			
		||||
                // FRAX ecosystem
 | 
			
		||||
@@ -889,6 +931,10 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
 | 
			
		||||
                builder
 | 
			
		||||
                    .add(MAINNET_TOKENS.OHMV2, MAINNET_TOKENS.BTRFLY)
 | 
			
		||||
                    .add(MAINNET_TOKENS.BTRFLY, MAINNET_TOKENS.OHMV2);
 | 
			
		||||
                // Lido
 | 
			
		||||
                builder
 | 
			
		||||
                    .add(MAINNET_TOKENS.stETH, MAINNET_TOKENS.wstETH)
 | 
			
		||||
                    .add(MAINNET_TOKENS.wstETH, MAINNET_TOKENS.stETH);
 | 
			
		||||
            })
 | 
			
		||||
            // Build
 | 
			
		||||
            .build(),
 | 
			
		||||
@@ -897,15 +943,21 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
 | 
			
		||||
        }).build(),
 | 
			
		||||
        [ChainId.Polygon]: new TokenAdjacencyGraphBuilder({
 | 
			
		||||
            default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Polygon],
 | 
			
		||||
        }).build(),
 | 
			
		||||
        })
 | 
			
		||||
            .tap(builder => {
 | 
			
		||||
                builder.add(POLYGON_TOKENS.QUICK, POLYGON_TOKENS.ANY).add(POLYGON_TOKENS.ANY, POLYGON_TOKENS.QUICK);
 | 
			
		||||
            })
 | 
			
		||||
            .build(),
 | 
			
		||||
        [ChainId.Avalanche]: new TokenAdjacencyGraphBuilder({
 | 
			
		||||
            default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Avalanche],
 | 
			
		||||
        })
 | 
			
		||||
            .tap(builder => {
 | 
			
		||||
                // Synape nETH/aWETH pool
 | 
			
		||||
                // Synapse nETH/aWETH pool
 | 
			
		||||
                builder
 | 
			
		||||
                    .add(AVALANCHE_TOKENS.aWETH, AVALANCHE_TOKENS.nETH)
 | 
			
		||||
                    .add(AVALANCHE_TOKENS.nETH, AVALANCHE_TOKENS.aWETH);
 | 
			
		||||
                // Trader Joe MAG/MIM pool
 | 
			
		||||
                builder.add(AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.MAG).add(AVALANCHE_TOKENS.MAG, AVALANCHE_TOKENS.MIM);
 | 
			
		||||
            })
 | 
			
		||||
            .build(),
 | 
			
		||||
        [ChainId.Fantom]: new TokenAdjacencyGraphBuilder({
 | 
			
		||||
@@ -1029,6 +1081,15 @@ const createCurveFactoryCryptoExchangePool = (info: { tokens: string[]; pool: st
 | 
			
		||||
    poolAddress: info.pool,
 | 
			
		||||
    gasSchedule: info.gasSchedule,
 | 
			
		||||
});
 | 
			
		||||
const MOBIUSMONEY_CELO_SHARED: CurveInfo = {
 | 
			
		||||
    exchangeFunctionSelector: CurveFunctionSelectors.swap,
 | 
			
		||||
    sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
 | 
			
		||||
    buyQuoteFunctionSelector: CurveFunctionSelectors.None,
 | 
			
		||||
    metaTokens: undefined,
 | 
			
		||||
    gasSchedule: 150e3,
 | 
			
		||||
    poolAddress: NULL_ADDRESS,
 | 
			
		||||
    tokens: [],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Mainnet Curve configuration
 | 
			
		||||
@@ -1301,6 +1362,21 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
        pool: CURVE_POOLS.btrflyweth,
 | 
			
		||||
        gasSchedule: 250e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.wethyfi]: createCurveFactoryCryptoExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.YFI],
 | 
			
		||||
        pool: CURVE_POOLS.wethyfi,
 | 
			
		||||
        gasSchedule: 250e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.stgusdc]: createCurveFactoryCryptoExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.STG, MAINNET_TOKENS.USDC],
 | 
			
		||||
        pool: CURVE_POOLS.stgusdc,
 | 
			
		||||
        gasSchedule: 250e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [CURVE_POOLS.cvxfxs]: createCurveFactoryCryptoExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.FXS, MAINNET_TOKENS.cvxFXS],
 | 
			
		||||
        pool: CURVE_POOLS.cvxfxs,
 | 
			
		||||
        gasSchedule: 390e3,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
@@ -1438,38 +1514,6 @@ export const CURVE_OPTIMISM_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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: 140e3,
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const SNOWSWAP_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    [SNOWSWAP_POOLS.yUSD]: createCurveExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.yUSD, MAINNET_TOKENS.ybCRV],
 | 
			
		||||
        pool: SNOWSWAP_POOLS.yUSD,
 | 
			
		||||
        gasSchedule: 990e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [SNOWSWAP_POOLS.yUSD]: createCurveExchangeUnderlyingPool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.yCRV, MAINNET_TOKENS.bCRV],
 | 
			
		||||
        pool: SNOWSWAP_POOLS.yUSD,
 | 
			
		||||
        gasSchedule: 990e3,
 | 
			
		||||
    }),
 | 
			
		||||
    [SNOWSWAP_POOLS.yVault]: createCurveExchangePool({
 | 
			
		||||
        tokens: [MAINNET_TOKENS.yDAI, MAINNET_TOKENS.yUSDC, MAINNET_TOKENS.yUSDT, MAINNET_TOKENS.yTUSD],
 | 
			
		||||
        pool: SNOWSWAP_POOLS.yVault,
 | 
			
		||||
        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],
 | 
			
		||||
@@ -1496,21 +1540,21 @@ export const XSIGMA_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
 | 
			
		||||
// Curve-like sources using custom selectors
 | 
			
		||||
export const SADDLE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    [SADDLE_POOLS.stables]: {
 | 
			
		||||
    [SADDLE_POOLS.stablesV2]: {
 | 
			
		||||
        exchangeFunctionSelector: CurveFunctionSelectors.swap,
 | 
			
		||||
        sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
 | 
			
		||||
        buyQuoteFunctionSelector: CurveFunctionSelectors.None,
 | 
			
		||||
        poolAddress: SADDLE_POOLS.stables,
 | 
			
		||||
        poolAddress: SADDLE_POOLS.stablesV2,
 | 
			
		||||
        tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT],
 | 
			
		||||
        metaTokens: undefined,
 | 
			
		||||
        gasSchedule: 150e3,
 | 
			
		||||
    },
 | 
			
		||||
    [SADDLE_POOLS.bitcoins]: {
 | 
			
		||||
    [SADDLE_POOLS.bitcoinsV2]: {
 | 
			
		||||
        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],
 | 
			
		||||
        poolAddress: SADDLE_POOLS.bitcoinsV2,
 | 
			
		||||
        tokens: [MAINNET_TOKENS.WBTC, MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.sBTC],
 | 
			
		||||
        metaTokens: undefined,
 | 
			
		||||
        gasSchedule: 150e3,
 | 
			
		||||
    },
 | 
			
		||||
@@ -1696,6 +1740,39 @@ export const FIREBIRDONESWAP_POLYGON_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const MOBIUSMONEY_CELO_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    [MOBIUSMONEY_CELO_POOLS.usdc_optics_v2]: {
 | 
			
		||||
        ...MOBIUSMONEY_CELO_SHARED,
 | 
			
		||||
        poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_optics_v2,
 | 
			
		||||
        tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.cUSDC_V2],
 | 
			
		||||
    },
 | 
			
		||||
    [MOBIUSMONEY_CELO_POOLS.weth_optics_v2]: {
 | 
			
		||||
        ...MOBIUSMONEY_CELO_SHARED,
 | 
			
		||||
        poolAddress: MOBIUSMONEY_CELO_POOLS.weth_optics_v2,
 | 
			
		||||
        tokens: [CELO_TOKENS.cETH, CELO_TOKENS.oWETH],
 | 
			
		||||
    },
 | 
			
		||||
    [MOBIUSMONEY_CELO_POOLS.pusdc_optics_v2]: {
 | 
			
		||||
        ...MOBIUSMONEY_CELO_SHARED,
 | 
			
		||||
        poolAddress: MOBIUSMONEY_CELO_POOLS.pusdc_optics_v2,
 | 
			
		||||
        tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.pUSDC_V2],
 | 
			
		||||
    },
 | 
			
		||||
    [MOBIUSMONEY_CELO_POOLS.usdc_allbridge_solana]: {
 | 
			
		||||
        ...MOBIUSMONEY_CELO_SHARED,
 | 
			
		||||
        poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_allbridge_solana,
 | 
			
		||||
        tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.asUSDC],
 | 
			
		||||
    },
 | 
			
		||||
    [MOBIUSMONEY_CELO_POOLS.usdc_poly_optics]: {
 | 
			
		||||
        ...MOBIUSMONEY_CELO_SHARED,
 | 
			
		||||
        poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_poly_optics,
 | 
			
		||||
        tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.pUSD],
 | 
			
		||||
    },
 | 
			
		||||
    [MOBIUSMONEY_CELO_POOLS.dai_optics_v2]: {
 | 
			
		||||
        ...MOBIUSMONEY_CELO_SHARED,
 | 
			
		||||
        poolAddress: MOBIUSMONEY_CELO_POOLS.dai_optics_v2,
 | 
			
		||||
        tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.DAI],
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const ACRYPTOS_ACS4USD_POOL_BSC_TOKENS = [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.DAI, BSC_TOKENS.USDC];
 | 
			
		||||
 | 
			
		||||
const createAcryptosMetaUsdPool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
 | 
			
		||||
@@ -1734,34 +1811,39 @@ export const ACRYPTOS_BSC_INFOS: { [name: string]: CurveInfo } = {
 | 
			
		||||
    }),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kyber reserve prefixes
 | 
			
		||||
 * 0xff Fed price reserve
 | 
			
		||||
 * 0xaa Automated price reserve
 | 
			
		||||
 * 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>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: {
 | 
			
		||||
            networkProxy: '0x9aab3f75489902f3a48495025729a0af77d4b11e',
 | 
			
		||||
            hintHandler: '0xa1C0Fa73c39CFBcC11ec9Eb1Afc665aba9996E2C',
 | 
			
		||||
            weth: MAINNET_TOKENS.WETH,
 | 
			
		||||
        },
 | 
			
		||||
        [ChainId.Ropsten]: {
 | 
			
		||||
            networkProxy: '0x818e6fecd516ecc3849daf6845e3ec868087b755',
 | 
			
		||||
            hintHandler: '0x63f773c026093eef988e803bdd5772dd235a8e71',
 | 
			
		||||
            weth: getContractAddressesForChainOrThrow(ChainId.Ropsten).etherToken,
 | 
			
		||||
        },
 | 
			
		||||
export const PLATYPUS_AVALANCHE_INFOS: { [name: string]: PlatypusInfo } = {
 | 
			
		||||
    [PLATYPUS_AVALANCHE_POOLS.usd]: {
 | 
			
		||||
        poolAddress: PLATYPUS_AVALANCHE_POOLS.usd,
 | 
			
		||||
        tokens: [
 | 
			
		||||
            AVALANCHE_TOKENS.USDT,
 | 
			
		||||
            AVALANCHE_TOKENS.USDC,
 | 
			
		||||
            AVALANCHE_TOKENS.DAI,
 | 
			
		||||
            AVALANCHE_TOKENS.nUSDC,
 | 
			
		||||
            AVALANCHE_TOKENS.USDt,
 | 
			
		||||
        ],
 | 
			
		||||
        gasSchedule: 300e3,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        networkProxy: NULL_ADDRESS,
 | 
			
		||||
        hintHandler: NULL_ADDRESS,
 | 
			
		||||
        weth: NULL_ADDRESS,
 | 
			
		||||
    [PLATYPUS_AVALANCHE_POOLS.yusd]: {
 | 
			
		||||
        poolAddress: PLATYPUS_AVALANCHE_POOLS.yusd,
 | 
			
		||||
        tokens: [AVALANCHE_TOKENS.YUSD, AVALANCHE_TOKENS.nUSDC],
 | 
			
		||||
        gasSchedule: 300e3,
 | 
			
		||||
    },
 | 
			
		||||
);
 | 
			
		||||
    [PLATYPUS_AVALANCHE_POOLS.frax]: {
 | 
			
		||||
        poolAddress: PLATYPUS_AVALANCHE_POOLS.frax,
 | 
			
		||||
        tokens: [AVALANCHE_TOKENS.FRAX, AVALANCHE_TOKENS.nUSDC],
 | 
			
		||||
        gasSchedule: 300e3,
 | 
			
		||||
    },
 | 
			
		||||
    [PLATYPUS_AVALANCHE_POOLS.mim]: {
 | 
			
		||||
        poolAddress: PLATYPUS_AVALANCHE_POOLS.mim,
 | 
			
		||||
        tokens: [AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.nUSDC],
 | 
			
		||||
        gasSchedule: 300e3,
 | 
			
		||||
    },
 | 
			
		||||
    [PLATYPUS_AVALANCHE_POOLS.sAVAX]: {
 | 
			
		||||
        poolAddress: PLATYPUS_AVALANCHE_POOLS.sAVAX,
 | 
			
		||||
        tokens: [AVALANCHE_TOKENS.WAVAX, AVALANCHE_TOKENS.sAVAX],
 | 
			
		||||
        gasSchedule: 300e3,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID = valueByChainId<LiquidityProviderRegistry>(
 | 
			
		||||
    {
 | 
			
		||||
@@ -1825,11 +1907,6 @@ export const CRYPTO_COM_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const LINKSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    { [ChainId.Mainnet]: '0xa7ece0911fe8c60bff9e99f8fafcdbe56e07aff1' },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const SHIBASWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: '0x03f7724180aa6b939894b5ca4314783b0b36b329',
 | 
			
		||||
@@ -1872,13 +1949,6 @@ export const MSTABLE_POOLS_BY_CHAIN_ID = valueByChainId(
 | 
			
		||||
    },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const OASIS_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: '0x5e3e0548935a83ad29fb2a9153d331dc6d49020f',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const KYBER_DMM_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: '0x1c87257f5e8609940bc751a07bb085bb7f8cdbe6',
 | 
			
		||||
@@ -1890,6 +1960,27 @@ export const KYBER_DMM_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const BISWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.BSC]: '0x3a6d8ca21d1cf76f653a67577fa0d27453350dd8',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const MDEX_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.BSC]: '0x7dae51bd3e3376b8c7c4900e9107f12be3af1ba8',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const KNIGHTSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.BSC]: '0x05e61e0cdcd2170a76f9568a110cee3afdd6c46f',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const MOONISWAP_REGISTRIES_BY_CHAIN_ID = valueByChainId(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: ['0xbaf9a5d4b0052359326a6cdab54babaa3a3a9643'],
 | 
			
		||||
@@ -1977,6 +2068,20 @@ export const BANCOR_REGISTRY_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const BANCORV3_NETWORK_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: '0xeef417e1d5cc832e619ae18d2f140de2999dd4fb',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const BANCORV3_NETWORK_INFO_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: '0x8e303d296851b320e6a697bacb979d13c9d6e760',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const SHELL_POOLS_BY_CHAIN_ID = valueByChainId(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: {
 | 
			
		||||
@@ -2052,11 +2157,13 @@ export const BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN = valueByChainId<string>(
 | 
			
		||||
export const LIDO_INFO_BY_CHAIN = valueByChainId<LidoInfo>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: {
 | 
			
		||||
            stEthToken: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84',
 | 
			
		||||
            stEthToken: MAINNET_TOKENS.stETH,
 | 
			
		||||
            wstEthToken: MAINNET_TOKENS.wstETH,
 | 
			
		||||
            wethToken: MAINNET_TOKENS.WETH,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        wstEthToken: NULL_ADDRESS,
 | 
			
		||||
        stEthToken: NULL_ADDRESS,
 | 
			
		||||
        wethToken: NULL_ADDRESS,
 | 
			
		||||
    },
 | 
			
		||||
@@ -2066,11 +2173,12 @@ export const BALANCER_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/ba
 | 
			
		||||
export const BALANCER_TOP_POOLS_FETCHED = 250;
 | 
			
		||||
export const BALANCER_MAX_POOLS_FETCHED = 3;
 | 
			
		||||
 | 
			
		||||
export const BALANCER_V2_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
 | 
			
		||||
export const BALANCER_V2_SUBGRAPH_URL_BY_CHAIN = valueByChainId(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2',
 | 
			
		||||
        [ChainId.Polygon]: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-polygon-v2',
 | 
			
		||||
    },
 | 
			
		||||
    'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2',
 | 
			
		||||
    null,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
 | 
			
		||||
@@ -2152,13 +2260,6 @@ export const APESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    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',
 | 
			
		||||
@@ -2166,13 +2267,6 @@ export const CHEESESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const JULSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.BSC]: '0xbd67d157502a23309db761c41965600c2ec788b2',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Polygon
 | 
			
		||||
//
 | 
			
		||||
@@ -2205,18 +2299,9 @@ export const WAULTSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const POLYDEX_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
export const MESHSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Polygon]: '0xe5c67ba380fb2f70a47b489e94bced486bb8fb74',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const JETSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.BSC]: '0xbe65b8f75b9f20f4c522e0067a3887fada714800',
 | 
			
		||||
        [ChainId.Polygon]: '0x5c6ec38fb0e2609672bdf628b1fd605a523e5923',
 | 
			
		||||
        [ChainId.Fantom]: '0x845e76a8691423fbc4ecb8dd77556cb61c09ee25',
 | 
			
		||||
        [ChainId.Polygon]: '0x10f4a785f458bc144e3706575924889954946639',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
@@ -2263,6 +2348,48 @@ export const SPOOKYSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const GMX_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Avalanche]: '0x5f719c2f1095f7b9fc68a68e35b51194f4b6abe8',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const GMX_READER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Avalanche]: '0x67b789d48c926006f5132bfce4e976f0a7a63d5d',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const GMX_VAULT_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Avalanche]: '0x9ab2de34a33fb459b538c43f251eb825645e8595',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const PLATYPUS_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Avalanche]: '0x73256ec7575d999c360c1eec118ecbefd8da7d12',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const YOSHI_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Fantom]: '0xe4a4642b19c4d0cba965673cd51422b1eda0a78d',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const VELODROME_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Optimism]: '0xa132dab612db5cb9fc9ac426a0cc215a3423f9c9',
 | 
			
		||||
    },
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>(
 | 
			
		||||
    {
 | 
			
		||||
        [ChainId.Mainnet]: [
 | 
			
		||||
@@ -2279,9 +2406,7 @@ export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSo
 | 
			
		||||
            ERC20BridgeSource.BakerySwap,
 | 
			
		||||
            ERC20BridgeSource.SushiSwap,
 | 
			
		||||
            ERC20BridgeSource.ApeSwap,
 | 
			
		||||
            ERC20BridgeSource.CafeSwap,
 | 
			
		||||
            ERC20BridgeSource.CheeseSwap,
 | 
			
		||||
            ERC20BridgeSource.JulSwap,
 | 
			
		||||
            ERC20BridgeSource.LiquidityProvider,
 | 
			
		||||
            ERC20BridgeSource.Native,
 | 
			
		||||
        ],
 | 
			
		||||
@@ -2320,12 +2445,8 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
    [ERC20BridgeSource.LiquidityProvider]: fillData => {
 | 
			
		||||
        return (fillData as LiquidityProviderFillData).gasCost || 100e3;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.Eth2Dai]: () => 400e3,
 | 
			
		||||
    [ERC20BridgeSource.Kyber]: () => 450e3,
 | 
			
		||||
    [ERC20BridgeSource.Curve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.CurveV2]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Swerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.SnowSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Nerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Synapse]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Belt]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
@@ -2335,14 +2456,19 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
    [ERC20BridgeSource.IronSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.XSigma]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.FirebirdOneSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.MobiusMoney]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.MultiBridge]: () => 350e3,
 | 
			
		||||
    [ERC20BridgeSource.UniswapV2]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.SushiSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.CryptoCom]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Linkswap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.ShibaSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.BiSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.MDex]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.KnightSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Balancer]: () => 120e3,
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: () => 100e3,
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: (fillData?: FillData) => {
 | 
			
		||||
        return 100e3 + ((fillData as BalancerV2BatchSwapFillData).swapSteps.length - 1) * 50e3;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.Cream]: () => 120e3,
 | 
			
		||||
    [ERC20BridgeSource.MStable]: () => 200e3,
 | 
			
		||||
    [ERC20BridgeSource.MakerPsm]: (fillData?: FillData) => {
 | 
			
		||||
@@ -2377,9 +2503,9 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
        }
 | 
			
		||||
        return gas;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.BancorV3]: () => 250e3, // revisit gas costs with wrap/unwrap
 | 
			
		||||
    [ERC20BridgeSource.KyberDmm]: (fillData?: FillData) => {
 | 
			
		||||
        // TODO: Different base cost if to/from ETH.
 | 
			
		||||
        let gas = 95e3;
 | 
			
		||||
        let gas = 170e3;
 | 
			
		||||
        const path = (fillData as UniswapV2FillData).tokenAddressPath;
 | 
			
		||||
        if (path.length > 2) {
 | 
			
		||||
            gas += (path.length - 2) * 65e3; // +65k for each hop.
 | 
			
		||||
@@ -2417,7 +2543,18 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
 | 
			
		||||
        return gas;
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.Lido]: () => 226e3,
 | 
			
		||||
    [ERC20BridgeSource.Lido]: (fillData?: FillData) => {
 | 
			
		||||
        const lidoFillData = fillData as LidoFillData;
 | 
			
		||||
        const wethAddress = NATIVE_FEE_TOKEN_BY_CHAIN_ID[ChainId.Mainnet];
 | 
			
		||||
        // WETH -> stETH
 | 
			
		||||
        if (lidoFillData.takerToken === wethAddress) {
 | 
			
		||||
            return 226e3;
 | 
			
		||||
        } else if (lidoFillData.takerToken === lidoFillData.stEthTokenAddress) {
 | 
			
		||||
            return 120e3;
 | 
			
		||||
        } else {
 | 
			
		||||
            return 95e3;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    [ERC20BridgeSource.AaveV2]: (fillData?: FillData) => {
 | 
			
		||||
        const aaveFillData = fillData as AaveV2FillData;
 | 
			
		||||
        // NOTE: The Aave deposit method is more expensive than the withdraw
 | 
			
		||||
@@ -2445,9 +2582,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
    [ERC20BridgeSource.PancakeSwapV2]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.BakerySwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.ApeSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.CafeSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.CheeseSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.JulSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.WaultSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.ACryptos]: fillData => (fillData as CurveFillData).pool.gasSchedule,
 | 
			
		||||
 | 
			
		||||
@@ -2457,14 +2592,15 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
    [ERC20BridgeSource.QuickSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.ComethSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Dfyn]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Polydex]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.JetSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.MeshSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Avalanche
 | 
			
		||||
    //
 | 
			
		||||
    [ERC20BridgeSource.Pangolin]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.TraderJoe]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.GMX]: () => 450e3,
 | 
			
		||||
    [ERC20BridgeSource.Platypus]: () => 450e3,
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Celo
 | 
			
		||||
@@ -2477,7 +2613,13 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
 | 
			
		||||
    [ERC20BridgeSource.MorpheusSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.SpiritSwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.SpookySwap]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Yoshi]: uniswapV2CloneGasSchedule,
 | 
			
		||||
    [ERC20BridgeSource.Beethovenx]: () => 100e3,
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Optimism
 | 
			
		||||
    //
 | 
			
		||||
    [ERC20BridgeSource.Velodrome]: () => 160e3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE };
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,15 @@ import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { DEFAULT_INFO_LOGGER, INVALID_SIGNATURE } from '../../constants';
 | 
			
		||||
import {
 | 
			
		||||
    AltRfqMakerAssetOfferings,
 | 
			
		||||
    AssetSwapperContractAddresses,
 | 
			
		||||
    MarketOperation,
 | 
			
		||||
    NativeOrderWithFillableAmounts,
 | 
			
		||||
    SignedNativeOrder,
 | 
			
		||||
} from '../../types';
 | 
			
		||||
import { QuoteRequestor } from '../quote_requestor';
 | 
			
		||||
import { getAltMarketInfo } from '../alt_mm_implementation_utils';
 | 
			
		||||
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../quote_requestor';
 | 
			
		||||
import { toSignedNativeOrder } from '../rfq_client_mappers';
 | 
			
		||||
import {
 | 
			
		||||
    getNativeAdjustedFillableAmountsFromMakerAmount,
 | 
			
		||||
    getNativeAdjustedFillableAmountsFromTakerAmount,
 | 
			
		||||
@@ -241,6 +244,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                dexQuotes,
 | 
			
		||||
            },
 | 
			
		||||
            isRfqSupported,
 | 
			
		||||
            blockNumber: blockNumber.toNumber(),
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -269,6 +273,7 @@ export class MarketOperationUtils {
 | 
			
		||||
 | 
			
		||||
        // Call the sampler contract.
 | 
			
		||||
        const samplerPromise = this._sampler.executeAsync(
 | 
			
		||||
            this._sampler.getBlockNumber(),
 | 
			
		||||
            this._sampler.getTokenDecimals([makerToken, takerToken]),
 | 
			
		||||
            // Get native order fillable amounts.
 | 
			
		||||
            this._sampler.getLimitOrderFillableMakerAmounts(nativeOrders, this.contractAddresses.exchangeProxy),
 | 
			
		||||
@@ -302,6 +307,7 @@ export class MarketOperationUtils {
 | 
			
		||||
 | 
			
		||||
        const [
 | 
			
		||||
            [
 | 
			
		||||
                blockNumber,
 | 
			
		||||
                tokenDecimals,
 | 
			
		||||
                orderFillableMakerAmounts,
 | 
			
		||||
                ethToMakerAssetRate,
 | 
			
		||||
@@ -342,6 +348,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                dexQuotes,
 | 
			
		||||
            },
 | 
			
		||||
            isRfqSupported,
 | 
			
		||||
            blockNumber: blockNumber.toNumber(),
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -372,6 +379,7 @@ export class MarketOperationUtils {
 | 
			
		||||
        const feeSourceFilters = this._feeSources.exclude(_opts.excludedFeeSources);
 | 
			
		||||
 | 
			
		||||
        const ops = [
 | 
			
		||||
            this._sampler.getBlockNumber(),
 | 
			
		||||
            ...batchNativeOrders.map(orders =>
 | 
			
		||||
                this._sampler.getLimitOrderFillableMakerAmounts(orders, this.contractAddresses.exchangeProxy),
 | 
			
		||||
            ),
 | 
			
		||||
@@ -396,13 +404,15 @@ export class MarketOperationUtils {
 | 
			
		||||
            ),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        const executeResults = await this._sampler.executeBatchAsync(ops);
 | 
			
		||||
        const [blockNumberRaw, ...executeResults] = await this._sampler.executeBatchAsync(ops);
 | 
			
		||||
        const batchOrderFillableMakerAmounts = executeResults.splice(0, batchNativeOrders.length) as BigNumber[][];
 | 
			
		||||
        const batchEthToTakerAssetRate = executeResults.splice(0, batchNativeOrders.length) as BigNumber[];
 | 
			
		||||
        const batchDexQuotes = executeResults.splice(0, batchNativeOrders.length) as DexSample[][][];
 | 
			
		||||
        const batchTokenDecimals = executeResults.splice(0, batchNativeOrders.length) as number[][];
 | 
			
		||||
        const inputAmountPerEth = ZERO_AMOUNT;
 | 
			
		||||
 | 
			
		||||
        const blockNumber: number = (blockNumberRaw as BigNumber).toNumber();
 | 
			
		||||
 | 
			
		||||
        return Promise.all(
 | 
			
		||||
            batchNativeOrders.map(async (nativeOrders, i) => {
 | 
			
		||||
                if (nativeOrders.length === 0) {
 | 
			
		||||
@@ -435,6 +445,7 @@ export class MarketOperationUtils {
 | 
			
		||||
                                twoHopQuotes: [],
 | 
			
		||||
                            },
 | 
			
		||||
                            isRfqSupported: false,
 | 
			
		||||
                            blockNumber,
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            bridgeSlippage: _opts.bridgeSlippage,
 | 
			
		||||
@@ -655,17 +666,49 @@ export class MarketOperationUtils {
 | 
			
		||||
            // Timing of RFQT lifecycle
 | 
			
		||||
            const timeStart = new Date().getTime();
 | 
			
		||||
            const { makerToken, takerToken } = nativeOrders[0].order;
 | 
			
		||||
 | 
			
		||||
            // Filter Alt Rfq Maker Asset Offerings to the current pair
 | 
			
		||||
            const filteredOfferings: AltRfqMakerAssetOfferings = {};
 | 
			
		||||
            if (rfqt.altRfqAssetOfferings) {
 | 
			
		||||
                const endpoints = Object.keys(rfqt.altRfqAssetOfferings);
 | 
			
		||||
                for (const endpoint of endpoints) {
 | 
			
		||||
                    // Get the current pair if being offered
 | 
			
		||||
                    const offering = getAltMarketInfo(rfqt.altRfqAssetOfferings[endpoint], makerToken, takerToken);
 | 
			
		||||
                    if (offering) {
 | 
			
		||||
                        filteredOfferings[endpoint] = [offering];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (rfqt.isIndicative) {
 | 
			
		||||
                // An indicative quote is being requested, and indicative quotes price-aware enabled
 | 
			
		||||
                // Make the RFQT request and then re-run the sampler if new orders come back.
 | 
			
		||||
                const indicativeQuotes = await rfqt.quoteRequestor.requestRfqtIndicativeQuotesAsync(
 | 
			
		||||
                    makerToken,
 | 
			
		||||
                    takerToken,
 | 
			
		||||
                    amount,
 | 
			
		||||
                    side,
 | 
			
		||||
                    wholeOrderPrice,
 | 
			
		||||
                    rfqt,
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                const indicativeQuotes =
 | 
			
		||||
                    rfqt.rfqClient !== undefined
 | 
			
		||||
                        ? ((
 | 
			
		||||
                              await rfqt.rfqClient.getV1PricesAsync({
 | 
			
		||||
                                  altRfqAssetOfferings: filteredOfferings,
 | 
			
		||||
                                  assetFillAmount: amount,
 | 
			
		||||
                                  chainId: this._sampler.chainId,
 | 
			
		||||
                                  comparisonPrice: wholeOrderPrice,
 | 
			
		||||
                                  integratorId: rfqt.integrator.integratorId,
 | 
			
		||||
                                  intentOnFilling: rfqt.intentOnFilling,
 | 
			
		||||
                                  makerToken,
 | 
			
		||||
                                  marketOperation: side,
 | 
			
		||||
                                  takerAddress: rfqt.takerAddress,
 | 
			
		||||
                                  takerToken,
 | 
			
		||||
                                  txOrigin: rfqt.txOrigin,
 | 
			
		||||
                              })
 | 
			
		||||
                          ).prices as V4RFQIndicativeQuoteMM[])
 | 
			
		||||
                        : await rfqt.quoteRequestor.requestRfqtIndicativeQuotesAsync(
 | 
			
		||||
                              makerToken,
 | 
			
		||||
                              takerToken,
 | 
			
		||||
                              amount,
 | 
			
		||||
                              side,
 | 
			
		||||
                              wholeOrderPrice,
 | 
			
		||||
                              rfqt,
 | 
			
		||||
                          );
 | 
			
		||||
                const deltaTime = new Date().getTime() - timeStart;
 | 
			
		||||
                DEFAULT_INFO_LOGGER({
 | 
			
		||||
                    rfqQuoteType: 'indicative',
 | 
			
		||||
@@ -679,14 +722,31 @@ export class MarketOperationUtils {
 | 
			
		||||
            } else {
 | 
			
		||||
                // A firm quote is being requested, and firm quotes price-aware enabled.
 | 
			
		||||
                // Ensure that `intentOnFilling` is enabled and make the request.
 | 
			
		||||
                const firmQuotes = await rfqt.quoteRequestor.requestRfqtFirmQuotesAsync(
 | 
			
		||||
                    makerToken,
 | 
			
		||||
                    takerToken,
 | 
			
		||||
                    amount,
 | 
			
		||||
                    side,
 | 
			
		||||
                    wholeOrderPrice,
 | 
			
		||||
                    rfqt,
 | 
			
		||||
                );
 | 
			
		||||
                const firmQuotes =
 | 
			
		||||
                    rfqt.rfqClient !== undefined
 | 
			
		||||
                        ? (
 | 
			
		||||
                              await rfqt.rfqClient.getV1QuotesAsync({
 | 
			
		||||
                                  altRfqAssetOfferings: filteredOfferings,
 | 
			
		||||
                                  assetFillAmount: amount,
 | 
			
		||||
                                  chainId: this._sampler.chainId,
 | 
			
		||||
                                  comparisonPrice: wholeOrderPrice,
 | 
			
		||||
                                  integratorId: rfqt.integrator.integratorId,
 | 
			
		||||
                                  intentOnFilling: rfqt.intentOnFilling,
 | 
			
		||||
                                  makerToken,
 | 
			
		||||
                                  marketOperation: side,
 | 
			
		||||
                                  takerAddress: rfqt.takerAddress,
 | 
			
		||||
                                  takerToken,
 | 
			
		||||
                                  txOrigin: rfqt.txOrigin,
 | 
			
		||||
                              })
 | 
			
		||||
                          ).quotes.map(toSignedNativeOrder)
 | 
			
		||||
                        : await rfqt.quoteRequestor.requestRfqtFirmQuotesAsync(
 | 
			
		||||
                              makerToken,
 | 
			
		||||
                              takerToken,
 | 
			
		||||
                              amount,
 | 
			
		||||
                              side,
 | 
			
		||||
                              wholeOrderPrice,
 | 
			
		||||
                              rfqt,
 | 
			
		||||
                          );
 | 
			
		||||
                const deltaTime = new Date().getTime() - timeStart;
 | 
			
		||||
                DEFAULT_INFO_LOGGER({
 | 
			
		||||
                    rfqQuoteType: 'firm',
 | 
			
		||||
@@ -769,7 +829,7 @@ export class MarketOperationUtils {
 | 
			
		||||
    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)) {
 | 
			
		||||
                if (!cache || cache.isFresh(takerToken, makerToken)) {
 | 
			
		||||
                    return Promise.resolve([]);
 | 
			
		||||
                }
 | 
			
		||||
                return cache.getFreshPoolsForPairAsync(takerToken, makerToken);
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import {
 | 
			
		||||
    AaveV2FillData,
 | 
			
		||||
    AggregationError,
 | 
			
		||||
    BalancerFillData,
 | 
			
		||||
    BalancerV2BatchSwapFillData,
 | 
			
		||||
    BalancerV2FillData,
 | 
			
		||||
    BancorFillData,
 | 
			
		||||
    CollapsedFill,
 | 
			
		||||
@@ -20,8 +21,8 @@ import {
 | 
			
		||||
    FinalUniswapV3FillData,
 | 
			
		||||
    GeistFillData,
 | 
			
		||||
    GenericRouterFillData,
 | 
			
		||||
    GMXFillData,
 | 
			
		||||
    KyberDmmFillData,
 | 
			
		||||
    KyberFillData,
 | 
			
		||||
    LidoFillData,
 | 
			
		||||
    LiquidityProviderFillData,
 | 
			
		||||
    MakerPsmFillData,
 | 
			
		||||
@@ -34,10 +35,12 @@ import {
 | 
			
		||||
    OptimizedMarketOrder,
 | 
			
		||||
    OptimizedMarketOrderBase,
 | 
			
		||||
    OrderDomain,
 | 
			
		||||
    PlatypusFillData,
 | 
			
		||||
    ShellFillData,
 | 
			
		||||
    UniswapV2FillData,
 | 
			
		||||
    UniswapV3FillData,
 | 
			
		||||
    UniswapV3PathAmount,
 | 
			
		||||
    VelodromeFillData,
 | 
			
		||||
} from './types';
 | 
			
		||||
 | 
			
		||||
// tslint:disable completed-docs
 | 
			
		||||
@@ -86,11 +89,9 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
        case ERC20BridgeSource.Balancer:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Balancer, 'Balancer');
 | 
			
		||||
        case ERC20BridgeSource.BalancerV2:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.BalancerV2, 'BalancerV2');
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.BalancerV2Batch, 'BalancerV2');
 | 
			
		||||
        case ERC20BridgeSource.Bancor:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Bancor, 'Bancor');
 | 
			
		||||
        // case ERC20BridgeSource.CoFiX:
 | 
			
		||||
        //    return encodeBridgeSourceId(BridgeProtocol.CoFiX, 'CoFiX');
 | 
			
		||||
        case ERC20BridgeSource.Curve:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Curve, 'Curve');
 | 
			
		||||
        case ERC20BridgeSource.Cream:
 | 
			
		||||
@@ -99,8 +100,6 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.CryptoCom, 'CryptoCom');
 | 
			
		||||
        case ERC20BridgeSource.Dodo:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Dodo, 'Dodo');
 | 
			
		||||
        case ERC20BridgeSource.Kyber:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Kyber, 'Kyber');
 | 
			
		||||
        case ERC20BridgeSource.LiquidityProvider:
 | 
			
		||||
            // "LiquidityProvider" is too long to encode (17 characters).
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Unknown, 'LP');
 | 
			
		||||
@@ -110,24 +109,16 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Mooniswap, 'Mooniswap');
 | 
			
		||||
        case ERC20BridgeSource.MStable:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.MStable, 'MStable');
 | 
			
		||||
        case ERC20BridgeSource.Eth2Dai:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Oasis, 'Eth2Dai');
 | 
			
		||||
        case ERC20BridgeSource.Shell:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Shell, 'Shell');
 | 
			
		||||
        case ERC20BridgeSource.SnowSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Curve, 'SnowSwap');
 | 
			
		||||
        case ERC20BridgeSource.SushiSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SushiSwap');
 | 
			
		||||
        case ERC20BridgeSource.Swerve:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Curve, 'Swerve');
 | 
			
		||||
        case ERC20BridgeSource.Uniswap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Uniswap, 'Uniswap');
 | 
			
		||||
        case ERC20BridgeSource.UniswapV2:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'UniswapV2');
 | 
			
		||||
        case ERC20BridgeSource.DodoV2:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.DodoV2, 'DodoV2');
 | 
			
		||||
        case ERC20BridgeSource.Linkswap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Linkswap');
 | 
			
		||||
        case ERC20BridgeSource.PancakeSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'PancakeSwap');
 | 
			
		||||
        case ERC20BridgeSource.PancakeSwapV2:
 | 
			
		||||
@@ -152,12 +143,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
            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');
 | 
			
		||||
        case ERC20BridgeSource.KyberDmm:
 | 
			
		||||
@@ -172,16 +159,12 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.CurveV2, 'CurveV2');
 | 
			
		||||
        case ERC20BridgeSource.WaultSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'WaultSwap');
 | 
			
		||||
        case ERC20BridgeSource.Polydex:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Polydex');
 | 
			
		||||
        case ERC20BridgeSource.FirebirdOneSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Nerve, 'FirebirdOneSwap');
 | 
			
		||||
        case ERC20BridgeSource.Lido:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Lido, 'Lido');
 | 
			
		||||
        case ERC20BridgeSource.ShibaSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'ShibaSwap');
 | 
			
		||||
        case ERC20BridgeSource.JetSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'JetSwap');
 | 
			
		||||
        case ERC20BridgeSource.IronSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Nerve, 'IronSwap');
 | 
			
		||||
        case ERC20BridgeSource.ACryptos:
 | 
			
		||||
@@ -200,12 +183,32 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpookySwap');
 | 
			
		||||
        case ERC20BridgeSource.MorpheusSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MorpheusSwap');
 | 
			
		||||
        case ERC20BridgeSource.Yoshi:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Yoshi');
 | 
			
		||||
        case ERC20BridgeSource.AaveV2:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'AaveV2');
 | 
			
		||||
        case ERC20BridgeSource.Compound:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Compound, 'Compound');
 | 
			
		||||
        case ERC20BridgeSource.Geist:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'Geist');
 | 
			
		||||
        case ERC20BridgeSource.MobiusMoney:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Nerve, 'MobiusMoney');
 | 
			
		||||
        case ERC20BridgeSource.BiSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'BiSwap');
 | 
			
		||||
        case ERC20BridgeSource.MDex:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MDex');
 | 
			
		||||
        case ERC20BridgeSource.KnightSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'KnightSwap');
 | 
			
		||||
        case ERC20BridgeSource.GMX:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.GMX, 'GMX');
 | 
			
		||||
        case ERC20BridgeSource.Platypus:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Platypus, 'Platypus');
 | 
			
		||||
        case ERC20BridgeSource.MeshSwap:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MeshSwap');
 | 
			
		||||
        case ERC20BridgeSource.BancorV3:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.BancorV3, 'BancorV3');
 | 
			
		||||
        case ERC20BridgeSource.Velodrome:
 | 
			
		||||
            return encodeBridgeSourceId(BridgeProtocol.Velodrome, 'Velodrome');
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(AggregationError.NoBridgeForSource);
 | 
			
		||||
    }
 | 
			
		||||
@@ -229,8 +232,6 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
    switch (order.source) {
 | 
			
		||||
        case ERC20BridgeSource.Curve:
 | 
			
		||||
        case ERC20BridgeSource.CurveV2:
 | 
			
		||||
        case ERC20BridgeSource.Swerve:
 | 
			
		||||
        case ERC20BridgeSource.SnowSwap:
 | 
			
		||||
        case ERC20BridgeSource.Nerve:
 | 
			
		||||
        case ERC20BridgeSource.Synapse:
 | 
			
		||||
        case ERC20BridgeSource.Belt:
 | 
			
		||||
@@ -241,6 +242,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
        case ERC20BridgeSource.FirebirdOneSwap:
 | 
			
		||||
        case ERC20BridgeSource.IronSwap:
 | 
			
		||||
        case ERC20BridgeSource.ACryptos:
 | 
			
		||||
        case ERC20BridgeSource.MobiusMoney:
 | 
			
		||||
            const curveFillData = (order as OptimizedMarketBridgeOrder<CurveFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([
 | 
			
		||||
                curveFillData.pool.poolAddress,
 | 
			
		||||
@@ -255,9 +257,18 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
            bridgeData = encoder.encode([balancerFillData.poolAddress]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.BalancerV2:
 | 
			
		||||
            {
 | 
			
		||||
                const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2BatchSwapFillData>).fillData;
 | 
			
		||||
                bridgeData = encoder.encode([
 | 
			
		||||
                    balancerV2FillData.vault,
 | 
			
		||||
                    balancerV2FillData.swapSteps,
 | 
			
		||||
                    balancerV2FillData.assets,
 | 
			
		||||
                ]);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Beethovenx:
 | 
			
		||||
            const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
 | 
			
		||||
            const { vault, poolId } = balancerV2FillData;
 | 
			
		||||
            const beethovenFillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
 | 
			
		||||
            const { vault, poolId } = beethovenFillData;
 | 
			
		||||
            bridgeData = encoder.encode([vault, poolId]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Bancor:
 | 
			
		||||
@@ -267,34 +278,30 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
        case ERC20BridgeSource.UniswapV2:
 | 
			
		||||
        case ERC20BridgeSource.SushiSwap:
 | 
			
		||||
        case ERC20BridgeSource.CryptoCom:
 | 
			
		||||
        case ERC20BridgeSource.Linkswap:
 | 
			
		||||
        case ERC20BridgeSource.PancakeSwap:
 | 
			
		||||
        case ERC20BridgeSource.PancakeSwapV2:
 | 
			
		||||
        case ERC20BridgeSource.BakerySwap:
 | 
			
		||||
        case ERC20BridgeSource.ApeSwap:
 | 
			
		||||
        case ERC20BridgeSource.CafeSwap:
 | 
			
		||||
        case ERC20BridgeSource.CheeseSwap:
 | 
			
		||||
        case ERC20BridgeSource.JulSwap:
 | 
			
		||||
        case ERC20BridgeSource.QuickSwap:
 | 
			
		||||
        case ERC20BridgeSource.ComethSwap:
 | 
			
		||||
        case ERC20BridgeSource.Dfyn:
 | 
			
		||||
        case ERC20BridgeSource.WaultSwap:
 | 
			
		||||
        case ERC20BridgeSource.Polydex:
 | 
			
		||||
        case ERC20BridgeSource.ShibaSwap:
 | 
			
		||||
        case ERC20BridgeSource.JetSwap:
 | 
			
		||||
        case ERC20BridgeSource.Pangolin:
 | 
			
		||||
        case ERC20BridgeSource.TraderJoe:
 | 
			
		||||
        case ERC20BridgeSource.UbeSwap:
 | 
			
		||||
        case ERC20BridgeSource.SpiritSwap:
 | 
			
		||||
        case ERC20BridgeSource.SpookySwap:
 | 
			
		||||
        case ERC20BridgeSource.MorpheusSwap:
 | 
			
		||||
        case ERC20BridgeSource.BiSwap:
 | 
			
		||||
        case ERC20BridgeSource.MDex:
 | 
			
		||||
        case ERC20BridgeSource.KnightSwap:
 | 
			
		||||
        case ERC20BridgeSource.Yoshi:
 | 
			
		||||
        case ERC20BridgeSource.MeshSwap:
 | 
			
		||||
            const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Kyber:
 | 
			
		||||
            const kyberFillData = (order as OptimizedMarketBridgeOrder<KyberFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([kyberFillData.networkProxy, kyberFillData.hint]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Mooniswap:
 | 
			
		||||
            const mooniswapFillData = (order as OptimizedMarketBridgeOrder<MooniswapFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([mooniswapFillData.poolAddress]);
 | 
			
		||||
@@ -324,10 +331,6 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
            const uniFillData = (order as OptimizedMarketBridgeOrder<GenericRouterFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([uniFillData.router]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Eth2Dai:
 | 
			
		||||
            const oasisFillData = (order as OptimizedMarketBridgeOrder<GenericRouterFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([oasisFillData.router]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.MStable:
 | 
			
		||||
            const mStableFillData = (order as OptimizedMarketBridgeOrder<GenericRouterFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([mStableFillData.router]);
 | 
			
		||||
@@ -350,7 +353,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Lido:
 | 
			
		||||
            const lidoFillData = (order as OptimizedMarketBridgeOrder<LidoFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([lidoFillData.stEthTokenAddress]);
 | 
			
		||||
            bridgeData = encoder.encode([lidoFillData.stEthTokenAddress, lidoFillData.wstEthTokenAddress]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.AaveV2:
 | 
			
		||||
            const aaveFillData = (order as OptimizedMarketBridgeOrder<AaveV2FillData>).fillData;
 | 
			
		||||
@@ -364,7 +367,31 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
 | 
			
		||||
            const geistFillData = (order as OptimizedMarketBridgeOrder<GeistFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([geistFillData.lendingPool, geistFillData.gToken]);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case ERC20BridgeSource.GMX:
 | 
			
		||||
            const gmxFillData = (order as OptimizedMarketBridgeOrder<GMXFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([
 | 
			
		||||
                gmxFillData.router,
 | 
			
		||||
                gmxFillData.reader,
 | 
			
		||||
                gmxFillData.vault,
 | 
			
		||||
                gmxFillData.tokenAddressPath,
 | 
			
		||||
            ]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Platypus:
 | 
			
		||||
            const platypusFillData = (order as OptimizedMarketBridgeOrder<PlatypusFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([
 | 
			
		||||
                platypusFillData.router,
 | 
			
		||||
                platypusFillData.pool,
 | 
			
		||||
                platypusFillData.tokenAddressPath,
 | 
			
		||||
            ]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.BancorV3:
 | 
			
		||||
            const bancorV3FillData = (order as OptimizedMarketBridgeOrder<BancorFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([bancorV3FillData.networkAddress, bancorV3FillData.path]);
 | 
			
		||||
            break;
 | 
			
		||||
        case ERC20BridgeSource.Velodrome:
 | 
			
		||||
            const velodromeFillData = (order as OptimizedMarketBridgeOrder<VelodromeFillData>).fillData;
 | 
			
		||||
            bridgeData = encoder.encode([velodromeFillData.router, velodromeFillData.stable]);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            throw new Error(AggregationError.NoBridgeForSource);
 | 
			
		||||
    }
 | 
			
		||||
@@ -450,6 +477,8 @@ const balancerV2Encoder = AbiEncoder.create([
 | 
			
		||||
]);
 | 
			
		||||
const routerAddressPathEncoder = AbiEncoder.create('(address,address[])');
 | 
			
		||||
const tokenAddressEncoder = AbiEncoder.create([{ name: 'tokenAddress', type: 'address' }]);
 | 
			
		||||
const gmxAddressPathEncoder = AbiEncoder.create('(address,address,address,address[])');
 | 
			
		||||
const platypusAddressPathEncoder = AbiEncoder.create('(address,address[],address[])');
 | 
			
		||||
 | 
			
		||||
export const BRIDGE_ENCODERS: {
 | 
			
		||||
    [key in Exclude<
 | 
			
		||||
@@ -461,10 +490,6 @@ export const BRIDGE_ENCODERS: {
 | 
			
		||||
        { name: 'provider', type: 'address' },
 | 
			
		||||
        { name: 'data', type: 'bytes' },
 | 
			
		||||
    ]),
 | 
			
		||||
    [ERC20BridgeSource.Kyber]: AbiEncoder.create([
 | 
			
		||||
        { name: 'kyberNetworkProxy', type: 'address' },
 | 
			
		||||
        { name: 'hint', type: 'bytes' },
 | 
			
		||||
    ]),
 | 
			
		||||
    [ERC20BridgeSource.Dodo]: AbiEncoder.create([
 | 
			
		||||
        { name: 'helper', type: 'address' },
 | 
			
		||||
        { name: 'poolAddress', type: 'address' },
 | 
			
		||||
@@ -477,8 +502,6 @@ export const BRIDGE_ENCODERS: {
 | 
			
		||||
    // Curve like
 | 
			
		||||
    [ERC20BridgeSource.Curve]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.CurveV2]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Swerve]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.SnowSwap]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Nerve]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Synapse]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Belt]: curveEncoder,
 | 
			
		||||
@@ -489,18 +512,27 @@ export const BRIDGE_ENCODERS: {
 | 
			
		||||
    [ERC20BridgeSource.FirebirdOneSwap]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.IronSwap]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.ACryptos]: curveEncoder,
 | 
			
		||||
    [ERC20BridgeSource.MobiusMoney]: curveEncoder,
 | 
			
		||||
    // UniswapV2 like, (router, address[])
 | 
			
		||||
    [ERC20BridgeSource.Bancor]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.BancorV3]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.UniswapV2]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.SushiSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.CryptoCom]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Linkswap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.ShibaSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Pangolin]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.TraderJoe]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.SpiritSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.MorpheusSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.BiSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.MDex]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.KnightSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Yoshi]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.MeshSwap]: routerAddressPathEncoder,
 | 
			
		||||
    // Avalanche
 | 
			
		||||
    [ERC20BridgeSource.GMX]: gmxAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Platypus]: platypusAddressPathEncoder,
 | 
			
		||||
    // Celo
 | 
			
		||||
    [ERC20BridgeSource.UbeSwap]: routerAddressPathEncoder,
 | 
			
		||||
    // BSC
 | 
			
		||||
@@ -508,38 +540,48 @@ export const BRIDGE_ENCODERS: {
 | 
			
		||||
    [ERC20BridgeSource.PancakeSwapV2]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.BakerySwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.ApeSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.CafeSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.CheeseSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.JulSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.WaultSwap]: routerAddressPathEncoder,
 | 
			
		||||
    // Polygon
 | 
			
		||||
    [ERC20BridgeSource.QuickSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.ComethSwap]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Dfyn]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Polydex]: routerAddressPathEncoder,
 | 
			
		||||
    [ERC20BridgeSource.JetSwap]: routerAddressPathEncoder,
 | 
			
		||||
    // Generic pools
 | 
			
		||||
    [ERC20BridgeSource.Shell]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Component]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Mooniswap]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Eth2Dai]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.MStable]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Balancer]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Cream]: poolEncoder,
 | 
			
		||||
    [ERC20BridgeSource.Uniswap]: poolEncoder,
 | 
			
		||||
    // Custom integrations
 | 
			
		||||
    [ERC20BridgeSource.MakerPsm]: makerPsmEncoder,
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: balancerV2Encoder,
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: AbiEncoder.create([
 | 
			
		||||
        { name: 'vault', type: 'address' },
 | 
			
		||||
        {
 | 
			
		||||
            name: 'swapSteps',
 | 
			
		||||
            type: 'tuple[]',
 | 
			
		||||
            components: [
 | 
			
		||||
                { name: 'poolId', type: 'bytes32' },
 | 
			
		||||
                { name: 'assetInIndex', type: 'uint256' },
 | 
			
		||||
                { name: 'assetOutIndex', type: 'uint256' },
 | 
			
		||||
                { name: 'amount', type: 'uint256' },
 | 
			
		||||
                { name: 'userData', type: 'bytes' },
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
        { name: 'assets', type: 'address[]' },
 | 
			
		||||
    ]),
 | 
			
		||||
    [ERC20BridgeSource.Beethovenx]: balancerV2Encoder,
 | 
			
		||||
    [ERC20BridgeSource.UniswapV3]: AbiEncoder.create([
 | 
			
		||||
        { name: 'router', type: 'address' },
 | 
			
		||||
        { name: 'path', type: 'bytes' },
 | 
			
		||||
    ]),
 | 
			
		||||
    [ERC20BridgeSource.KyberDmm]: AbiEncoder.create('(address,address[],address[])'),
 | 
			
		||||
    [ERC20BridgeSource.Lido]: AbiEncoder.create('(address)'),
 | 
			
		||||
    [ERC20BridgeSource.Lido]: AbiEncoder.create('(address,address)'),
 | 
			
		||||
    [ERC20BridgeSource.AaveV2]: AbiEncoder.create('(address,address)'),
 | 
			
		||||
    [ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'),
 | 
			
		||||
    [ERC20BridgeSource.Geist]: AbiEncoder.create('(address,address)'),
 | 
			
		||||
    [ERC20BridgeSource.Velodrome]: AbiEncoder.create('(address,bool)'),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {
 | 
			
		||||
 
 | 
			
		||||
@@ -227,8 +227,9 @@ function findRoutesAndCreateOptimalPath(
 | 
			
		||||
        const sourcePathId = hexUtils.random();
 | 
			
		||||
        const singleSourceSamplesWithOutput = [...singleSourceSamples];
 | 
			
		||||
        for (let i = singleSourceSamples.length - 1; i >= 0; i--) {
 | 
			
		||||
            if (singleSourceSamples[i].output.isZero()) {
 | 
			
		||||
                // Remove trailing 0 output samples
 | 
			
		||||
            const currentOutput = singleSourceSamples[i].output;
 | 
			
		||||
            if (currentOutput.isZero() || !currentOutput.isFinite()) {
 | 
			
		||||
                // Remove trailing 0/invalid output samples
 | 
			
		||||
                singleSourceSamplesWithOutput.pop();
 | 
			
		||||
            } else {
 | 
			
		||||
                break;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from '@balancer-labs/sor';
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from 'balancer-labs-sor-v1';
 | 
			
		||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
 | 
			
		||||
import { gql, request } from 'graphql-request';
 | 
			
		||||
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_SUBGRAPH_URL, BALANCER_TOP_POOLS_FETCHED } from '../constants';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import { ChainId } from '@0x/contract-addresses';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
// import { parsePoolData } from '@balancer-labs'; // TODO - upgrade to v2
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
 | 
			
		||||
import { gql, request } from 'graphql-request';
 | 
			
		||||
 | 
			
		||||
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
 | 
			
		||||
@@ -51,7 +51,7 @@ export class BalancerV2PoolsCache extends PoolsCache {
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        chainId: ChainId,
 | 
			
		||||
        private readonly subgraphUrl: string = BALANCER_V2_SUBGRAPH_URL_BY_CHAIN[chainId],
 | 
			
		||||
        private readonly subgraphUrl: string = BALANCER_V2_SUBGRAPH_URL_BY_CHAIN[chainId]!,
 | 
			
		||||
        private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
 | 
			
		||||
        private readonly _topPoolsFetched: number = BALANCER_TOP_POOLS_FETCHED,
 | 
			
		||||
        private readonly _warningLogger: LogFunction = DEFAULT_WARNING_LOGGER,
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,190 @@
 | 
			
		||||
import { ChainId } from '@0x/contract-addresses';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import {
 | 
			
		||||
    BalancerSDK,
 | 
			
		||||
    BalancerSdkConfig,
 | 
			
		||||
    formatSequence,
 | 
			
		||||
    getTokenAddressesForSwap,
 | 
			
		||||
    NewPath,
 | 
			
		||||
    parseToPoolsDict,
 | 
			
		||||
    PoolDictionary,
 | 
			
		||||
    RouteProposer,
 | 
			
		||||
    SwapTypes,
 | 
			
		||||
} from '@balancer-labs/sdk';
 | 
			
		||||
 | 
			
		||||
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
 | 
			
		||||
import { LogFunction } from '../../../types';
 | 
			
		||||
import { BALANCER_V2_SUBGRAPH_URL_BY_CHAIN, ONE_SECOND_MS } from '../constants';
 | 
			
		||||
import { BalancerSwapInfo, BalancerSwaps } from '../types';
 | 
			
		||||
 | 
			
		||||
import { CacheValue, EMPTY_BALANCER_SWAPS, SwapInfoCache } from './pair_swaps_cache';
 | 
			
		||||
import { SubgraphPoolDataService } from './sgPoolDataService';
 | 
			
		||||
 | 
			
		||||
// tslint:disable-next-line:custom-no-magic-numbers
 | 
			
		||||
const ONE_DAY_MS = 24 * 60 * 60 * ONE_SECOND_MS;
 | 
			
		||||
 | 
			
		||||
export interface BalancerPoolResponse {
 | 
			
		||||
    poolType: string;
 | 
			
		||||
    id: string;
 | 
			
		||||
    tokens: Array<{ address: string }>;
 | 
			
		||||
    tokensList: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class BalancerV2SwapInfoCache extends SwapInfoCache {
 | 
			
		||||
    private static readonly _MAX_POOLS_PER_PATH = 4;
 | 
			
		||||
    private static readonly _MAX_CANDIDATE_PATHS_PER_PAIR = 2;
 | 
			
		||||
    private readonly _routeProposer: RouteProposer;
 | 
			
		||||
    private readonly _poolDataService: SubgraphPoolDataService;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        chainId: ChainId,
 | 
			
		||||
        subgraphUrl: string | null = BALANCER_V2_SUBGRAPH_URL_BY_CHAIN[chainId],
 | 
			
		||||
        private readonly _warningLogger: LogFunction = DEFAULT_WARNING_LOGGER,
 | 
			
		||||
        cache: { [key: string]: CacheValue } = {},
 | 
			
		||||
    ) {
 | 
			
		||||
        super(cache);
 | 
			
		||||
        const config: BalancerSdkConfig = {
 | 
			
		||||
            network: chainId as number, // wtf TS
 | 
			
		||||
            rpcUrl: '', // Not actually used by SDK for this.
 | 
			
		||||
        };
 | 
			
		||||
        const balancerSdk = new BalancerSDK(config);
 | 
			
		||||
        // The RouteProposer finds paths between a token pair using direct/multihop/linearPool routes
 | 
			
		||||
        this._routeProposer = balancerSdk.sor.routeProposer;
 | 
			
		||||
        // Uses Subgraph to retrieve up to date pool data required for routeProposer
 | 
			
		||||
        this._poolDataService = new SubgraphPoolDataService({
 | 
			
		||||
            chainId,
 | 
			
		||||
            subgraphUrl,
 | 
			
		||||
        });
 | 
			
		||||
        void this._loadTopPoolsAsync();
 | 
			
		||||
        // Reload the top pools every 12 hours
 | 
			
		||||
        setInterval(async () => void this._loadTopPoolsAsync(), ONE_DAY_MS / 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _loadTopPoolsAsync(): Promise<void> {
 | 
			
		||||
        const fromToSwapInfo: {
 | 
			
		||||
            [from: string]: { [to: string]: BalancerSwaps };
 | 
			
		||||
        } = {};
 | 
			
		||||
 | 
			
		||||
        // Retrieve pool data from Subgraph
 | 
			
		||||
        const pools = await this._poolDataService.getPools();
 | 
			
		||||
        // timestamp is used for Element pools
 | 
			
		||||
        const timestamp = Math.floor(Date.now() / ONE_SECOND_MS);
 | 
			
		||||
        const poolsDict = parseToPoolsDict(pools, timestamp);
 | 
			
		||||
 | 
			
		||||
        for (const pool of pools) {
 | 
			
		||||
            const { tokensList } = pool;
 | 
			
		||||
            // tslint:disable-next-line: await-promise
 | 
			
		||||
            await null; // This loop can be CPU heavy so yield to event loop.
 | 
			
		||||
            for (const from of tokensList) {
 | 
			
		||||
                for (const to of tokensList.filter(t => t.toLowerCase() !== from.toLowerCase())) {
 | 
			
		||||
                    fromToSwapInfo[from] = fromToSwapInfo[from] || {};
 | 
			
		||||
                    // If a record for pair already exists skip as all paths alreay found
 | 
			
		||||
                    if (fromToSwapInfo[from][to]) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        try {
 | 
			
		||||
                            const expiresAt = Date.now() + this._cacheTimeMs;
 | 
			
		||||
                            // Retrieve swap steps and assets for a token pair
 | 
			
		||||
                            // This only needs to be called once per pair as all paths will be created from single call
 | 
			
		||||
                            const pairSwapInfo = this._getPoolPairSwapInfo(poolsDict, from, to);
 | 
			
		||||
                            fromToSwapInfo[from][to] = pairSwapInfo;
 | 
			
		||||
                            this._cacheSwapInfoForPair(from, to, fromToSwapInfo[from][to], expiresAt);
 | 
			
		||||
                        } catch (err) {
 | 
			
		||||
                            this._warningLogger(err, `Failed to load Balancer V2 top pools`);
 | 
			
		||||
                            // soldier on
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Will retrieve fresh pair and path data from Subgraph and return and array of swap info for pair..
 | 
			
		||||
     * @param takerToken Address of takerToken.
 | 
			
		||||
     * @param makerToken Address of makerToken.
 | 
			
		||||
     * @returns Swap data for pair consisting of assets and swap steps for ExactIn and ExactOut swap types.
 | 
			
		||||
     */
 | 
			
		||||
    protected async _fetchSwapInfoForPairAsync(takerToken: string, makerToken: string): Promise<BalancerSwaps> {
 | 
			
		||||
        try {
 | 
			
		||||
            // retrieve up to date pools from SG
 | 
			
		||||
            const pools = await this._poolDataService.getPools();
 | 
			
		||||
 | 
			
		||||
            // timestamp is used for Element pools
 | 
			
		||||
            const timestamp = Math.floor(Date.now() / ONE_SECOND_MS);
 | 
			
		||||
            const poolDictionary = parseToPoolsDict(pools, timestamp);
 | 
			
		||||
            return this._getPoolPairSwapInfo(poolDictionary, takerToken, makerToken);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            return EMPTY_BALANCER_SWAPS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Uses pool data from provided dictionary to find top swap paths for token pair.
 | 
			
		||||
     * @param pools Dictionary of pool data.
 | 
			
		||||
     * @param takerToken Address of taker token.
 | 
			
		||||
     * @param makerToken Address of maker token.
 | 
			
		||||
     * @returns Swap data for pair consisting of assets and swap steps for ExactIn and ExactOut swap types.
 | 
			
		||||
     */
 | 
			
		||||
    private _getPoolPairSwapInfo(pools: PoolDictionary, takerToken: string, makerToken: string): BalancerSwaps {
 | 
			
		||||
        /*
 | 
			
		||||
        Uses Balancer SDK to construct available paths for pair.
 | 
			
		||||
        Paths can be direct, i.e. both tokens are in same pool or multihop.
 | 
			
		||||
        Will also create paths for the new Balancer Linear pools.
 | 
			
		||||
        These are returned in order of available liquidity which is useful for filtering.
 | 
			
		||||
        */
 | 
			
		||||
        const paths = this._routeProposer.getCandidatePathsFromDict(
 | 
			
		||||
            takerToken,
 | 
			
		||||
            makerToken,
 | 
			
		||||
            SwapTypes.SwapExactIn,
 | 
			
		||||
            pools,
 | 
			
		||||
            BalancerV2SwapInfoCache._MAX_POOLS_PER_PATH,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (paths.length === 0) {
 | 
			
		||||
            return EMPTY_BALANCER_SWAPS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Convert paths data to swap information suitable for queryBatchSwap. Only use top 2 liquid paths
 | 
			
		||||
        return formatSwaps(paths.slice(0, BalancerV2SwapInfoCache._MAX_CANDIDATE_PATHS_PER_PAIR));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Given an array of Balancer paths, returns swap information that can be passed to queryBatchSwap.
 | 
			
		||||
 * @param paths Array of Balancer paths.
 | 
			
		||||
 * @returns Formatted swap data consisting of assets and swap steps for ExactIn and ExactOut swap types.
 | 
			
		||||
 */
 | 
			
		||||
function formatSwaps(paths: NewPath[]): BalancerSwaps {
 | 
			
		||||
    const formattedSwapsExactIn: BalancerSwapInfo[] = [];
 | 
			
		||||
    const formattedSwapsExactOut: BalancerSwapInfo[] = [];
 | 
			
		||||
    let assets: string[];
 | 
			
		||||
    paths.forEach(path => {
 | 
			
		||||
        // Add a swap amount for each swap so we can use formatSequence. (This will be overwritten with actual amount during query)
 | 
			
		||||
        path.swaps.forEach(s => (s.swapAmount = '0'));
 | 
			
		||||
        const tokenAddresses = getTokenAddressesForSwap(path.swaps);
 | 
			
		||||
        // Formats for both ExactIn and ExactOut swap types
 | 
			
		||||
        const swapsExactIn = formatSequence(SwapTypes.SwapExactIn, path.swaps, tokenAddresses);
 | 
			
		||||
        const swapsExactOut = formatSequence(SwapTypes.SwapExactOut, path.swaps, tokenAddresses);
 | 
			
		||||
        assets = tokenAddresses;
 | 
			
		||||
        formattedSwapsExactIn.push({
 | 
			
		||||
            assets,
 | 
			
		||||
            swapSteps: swapsExactIn.map(s => ({
 | 
			
		||||
                ...s,
 | 
			
		||||
                amount: new BigNumber(s.amount),
 | 
			
		||||
            })),
 | 
			
		||||
        });
 | 
			
		||||
        formattedSwapsExactOut.push({
 | 
			
		||||
            assets,
 | 
			
		||||
            swapSteps: swapsExactOut.map(s => ({
 | 
			
		||||
                ...s,
 | 
			
		||||
                amount: new BigNumber(s.amount),
 | 
			
		||||
            })),
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    const formattedSwaps: BalancerSwaps = {
 | 
			
		||||
        swapInfoExactIn: formattedSwapsExactIn,
 | 
			
		||||
        swapInfoExactOut: formattedSwapsExactOut,
 | 
			
		||||
    };
 | 
			
		||||
    return formattedSwaps;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
 | 
			
		||||
import { getPoolsWithTokens, parsePoolData } from 'cream-sor';
 | 
			
		||||
 | 
			
		||||
import { BALANCER_MAX_POOLS_FETCHED } from '../constants';
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,91 @@
 | 
			
		||||
import { BalancerSwaps } from '../types';
 | 
			
		||||
 | 
			
		||||
import { ONE_HOUR_IN_SECONDS, ONE_SECOND_MS } from '../constants';
 | 
			
		||||
 | 
			
		||||
export interface CacheValue {
 | 
			
		||||
    expiresAt: number;
 | 
			
		||||
    balancerSwaps: BalancerSwaps;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 = ONE_SECOND_MS;
 | 
			
		||||
export const EMPTY_BALANCER_SWAPS = { swapInfoExactIn: [], swapInfoExactOut: [] };
 | 
			
		||||
// tslint:enable:custom-no-magic-numbers
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Caches SwapInfo for a pair of tokens.
 | 
			
		||||
 * SwapInfo includes swap steps and asset information for those swap steps.
 | 
			
		||||
 */
 | 
			
		||||
export abstract class SwapInfoCache {
 | 
			
		||||
    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<BalancerSwaps> {
 | 
			
		||||
        const timeout = new Promise<BalancerSwaps>(resolve => setTimeout(resolve, timeoutMs, []));
 | 
			
		||||
        return Promise.race([this._getAndSaveFreshSwapInfoForPairAsync(takerToken, makerToken), timeout]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getCachedSwapInfoForPair(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        ignoreExpired: boolean = true,
 | 
			
		||||
    ): BalancerSwaps | undefined {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        if (ignoreExpired) {
 | 
			
		||||
            return value === undefined ? EMPTY_BALANCER_SWAPS : value.balancerSwaps;
 | 
			
		||||
        }
 | 
			
		||||
        if (!value) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        if (SwapInfoCache._isExpired(value)) {
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
        return value.balancerSwaps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public isFresh(takerToken: string, makerToken: string): boolean {
 | 
			
		||||
        const cached = this.getCachedSwapInfoForPair(takerToken, makerToken, false);
 | 
			
		||||
        return cached !== undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected async _getAndSaveFreshSwapInfoForPairAsync(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
    ): Promise<BalancerSwaps> {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        const value = this._cache[key];
 | 
			
		||||
        if (value === undefined || value.expiresAt >= Date.now()) {
 | 
			
		||||
            const swapInfo = await this._fetchSwapInfoForPairAsync(takerToken, makerToken);
 | 
			
		||||
            const expiresAt = Date.now() + this._cacheTimeMs;
 | 
			
		||||
            this._cacheSwapInfoForPair(takerToken, makerToken, swapInfo, expiresAt);
 | 
			
		||||
        }
 | 
			
		||||
        return this._cache[key].balancerSwaps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected _cacheSwapInfoForPair(
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        swapInfo: BalancerSwaps,
 | 
			
		||||
        expiresAt: number,
 | 
			
		||||
    ): void {
 | 
			
		||||
        const key = JSON.stringify([takerToken, makerToken]);
 | 
			
		||||
        this._cache[key] = {
 | 
			
		||||
            expiresAt,
 | 
			
		||||
            balancerSwaps: swapInfo,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract _fetchSwapInfoForPairAsync(takerToken: string, makerToken: string): Promise<BalancerSwaps>;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
 | 
			
		||||
 | 
			
		||||
import { ONE_HOUR_IN_SECONDS, ONE_SECOND_MS } from '../constants';
 | 
			
		||||
export { Pool };
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,114 @@
 | 
			
		||||
import { ChainId } from '@0x/contract-addresses';
 | 
			
		||||
import { logUtils } from '@0x/utils';
 | 
			
		||||
import { PoolDataService, SubgraphPoolBase } from '@balancer-labs/sdk';
 | 
			
		||||
import { gql, request } from 'graphql-request';
 | 
			
		||||
 | 
			
		||||
const queryWithLinear = gql`
 | 
			
		||||
    query fetchTopPoolsWithLinear($maxPoolsFetched: Int!) {
 | 
			
		||||
        pools: pools(
 | 
			
		||||
            first: $maxPoolsFetched
 | 
			
		||||
            where: { swapEnabled: true }
 | 
			
		||||
            orderBy: totalLiquidity
 | 
			
		||||
            orderDirection: desc
 | 
			
		||||
        ) {
 | 
			
		||||
            id
 | 
			
		||||
            address
 | 
			
		||||
            poolType
 | 
			
		||||
            swapFee
 | 
			
		||||
            totalShares
 | 
			
		||||
            tokens {
 | 
			
		||||
                address
 | 
			
		||||
                balance
 | 
			
		||||
                decimals
 | 
			
		||||
                weight
 | 
			
		||||
                priceRate
 | 
			
		||||
            }
 | 
			
		||||
            tokensList
 | 
			
		||||
            totalWeight
 | 
			
		||||
            amp
 | 
			
		||||
            expiryTime
 | 
			
		||||
            unitSeconds
 | 
			
		||||
            principalToken
 | 
			
		||||
            baseToken
 | 
			
		||||
            swapEnabled
 | 
			
		||||
            wrappedIndex
 | 
			
		||||
            mainIndex
 | 
			
		||||
            lowerTarget
 | 
			
		||||
            upperTarget
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
const queryWithOutLinear = gql`
 | 
			
		||||
    query fetchTopPoolsWithoutLinear($maxPoolsFetched: Int!) {
 | 
			
		||||
        pools: pools(
 | 
			
		||||
            first: $maxPoolsFetched
 | 
			
		||||
            where: { swapEnabled: true }
 | 
			
		||||
            orderBy: totalLiquidity
 | 
			
		||||
            orderDirection: desc
 | 
			
		||||
        ) {
 | 
			
		||||
            id
 | 
			
		||||
            address
 | 
			
		||||
            poolType
 | 
			
		||||
            swapFee
 | 
			
		||||
            totalShares
 | 
			
		||||
            tokens {
 | 
			
		||||
                address
 | 
			
		||||
                balance
 | 
			
		||||
                decimals
 | 
			
		||||
                weight
 | 
			
		||||
                priceRate
 | 
			
		||||
            }
 | 
			
		||||
            tokensList
 | 
			
		||||
            totalWeight
 | 
			
		||||
            amp
 | 
			
		||||
            expiryTime
 | 
			
		||||
            unitSeconds
 | 
			
		||||
            principalToken
 | 
			
		||||
            baseToken
 | 
			
		||||
            swapEnabled
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
const QUERY_BY_CHAIN_ID: { [chainId: number]: string } = {
 | 
			
		||||
    [ChainId.Mainnet]: queryWithLinear,
 | 
			
		||||
    [ChainId.Polygon]: queryWithOutLinear,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const DEFAULT_MAX_POOLS_FETCHED = 96;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Simple service to query required info from Subgraph for Balancer Pools.
 | 
			
		||||
 * Because Balancer Subgraphs have slightly different schema depending on network the queries are adjusted as needed.
 | 
			
		||||
 */
 | 
			
		||||
export class SubgraphPoolDataService implements PoolDataService {
 | 
			
		||||
    private readonly _gqlQuery: string | undefined;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private readonly _config: {
 | 
			
		||||
            chainId: number;
 | 
			
		||||
            subgraphUrl: string | null;
 | 
			
		||||
            maxPoolsFetched?: number;
 | 
			
		||||
        },
 | 
			
		||||
    ) {
 | 
			
		||||
        this._config.maxPoolsFetched = this._config.maxPoolsFetched || DEFAULT_MAX_POOLS_FETCHED;
 | 
			
		||||
        this._gqlQuery = QUERY_BY_CHAIN_ID[this._config.chainId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // tslint:disable-next-line: async-suffix
 | 
			
		||||
    public async getPools(): Promise<SubgraphPoolBase[]> {
 | 
			
		||||
        if (!this._gqlQuery || !this._config.subgraphUrl) {
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            const { pools } = await request<{ pools: SubgraphPoolBase[] }>(this._config.subgraphUrl, this._gqlQuery, {
 | 
			
		||||
                maxPoolsFetched: this._config.maxPoolsFetched,
 | 
			
		||||
            });
 | 
			
		||||
            return pools;
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
            logUtils.warn(`Failed to fetch BalancerV2 subgraph pools: ${err.message}`);
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -5,9 +5,8 @@ import { SamplerOverrides } from '../../types';
 | 
			
		||||
import { ERC20BridgeSamplerContract } from '../../wrappers';
 | 
			
		||||
 | 
			
		||||
import { BancorService } from './bancor_service';
 | 
			
		||||
import { PoolsCache } from './pools_cache';
 | 
			
		||||
import { SamplerOperations } from './sampler_operations';
 | 
			
		||||
import { BatchedOperation, ERC20BridgeSource, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
 | 
			
		||||
import { PoolsCacheMap, SamplerOperations } from './sampler_operations';
 | 
			
		||||
import { BatchedOperation, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate sample amounts up to `maxFillAmount`.
 | 
			
		||||
@@ -37,7 +36,7 @@ export class DexOrderSampler extends SamplerOperations {
 | 
			
		||||
        public readonly chainId: ChainId,
 | 
			
		||||
        _samplerContract: ERC20BridgeSamplerContract,
 | 
			
		||||
        private readonly _samplerOverrides?: SamplerOverrides,
 | 
			
		||||
        poolsCaches?: { [key in ERC20BridgeSource]: PoolsCache },
 | 
			
		||||
        poolsCaches?: PoolsCacheMap,
 | 
			
		||||
        tokenAdjacencyGraph?: TokenAdjacencyGraph,
 | 
			
		||||
        liquidityProviderRegistry?: LiquidityProviderRegistry,
 | 
			
		||||
        bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,8 @@ import { BancorService } from './bancor_service';
 | 
			
		||||
import {
 | 
			
		||||
    getCurveLikeInfosForPair,
 | 
			
		||||
    getDodoV2Offsets,
 | 
			
		||||
    getKyberOffsets,
 | 
			
		||||
    getPlatypusInfoForPair,
 | 
			
		||||
    getShellLikeInfosForPair,
 | 
			
		||||
    isAllowedKyberReserveId,
 | 
			
		||||
    isBadTokenForSource,
 | 
			
		||||
    isValidAddress,
 | 
			
		||||
    uniswapV2LikeRouterAddress,
 | 
			
		||||
@@ -23,17 +22,21 @@ import {
 | 
			
		||||
import { CompoundCTokenCache } from './compound_ctoken_cache';
 | 
			
		||||
import {
 | 
			
		||||
    AAVE_V2_SUBGRAPH_URL_BY_CHAIN_ID,
 | 
			
		||||
    AVALANCHE_TOKENS,
 | 
			
		||||
    BALANCER_V2_VAULT_ADDRESS_BY_CHAIN,
 | 
			
		||||
    BANCOR_REGISTRY_BY_CHAIN_ID,
 | 
			
		||||
    BANCORV3_NETWORK_BY_CHAIN_ID,
 | 
			
		||||
    BANCORV3_NETWORK_INFO_BY_CHAIN_ID,
 | 
			
		||||
    BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN,
 | 
			
		||||
    BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN,
 | 
			
		||||
    COMPOUND_API_URL_BY_CHAIN_ID,
 | 
			
		||||
    DODOV1_CONFIG_BY_CHAIN_ID,
 | 
			
		||||
    DODOV2_FACTORIES_BY_CHAIN_ID,
 | 
			
		||||
    KYBER_CONFIG_BY_CHAIN_ID,
 | 
			
		||||
    GMX_READER_BY_CHAIN_ID,
 | 
			
		||||
    GMX_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    GMX_VAULT_BY_CHAIN_ID,
 | 
			
		||||
    KYBER_DMM_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    LIDO_INFO_BY_CHAIN,
 | 
			
		||||
    LINKSWAP_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID,
 | 
			
		||||
    MAINNET_TOKENS,
 | 
			
		||||
    MAKER_PSM_INFO_BY_CHAIN_ID,
 | 
			
		||||
@@ -41,16 +44,18 @@ import {
 | 
			
		||||
    MOONISWAP_REGISTRIES_BY_CHAIN_ID,
 | 
			
		||||
    NATIVE_FEE_TOKEN_BY_CHAIN_ID,
 | 
			
		||||
    NULL_ADDRESS,
 | 
			
		||||
    NULL_BYTES,
 | 
			
		||||
    PLATYPUS_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    SELL_SOURCE_FILTER_BY_CHAIN_ID,
 | 
			
		||||
    UNISWAPV1_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    UNISWAPV3_CONFIG_BY_CHAIN_ID,
 | 
			
		||||
    VELODROME_ROUTER_BY_CHAIN_ID,
 | 
			
		||||
    ZERO_AMOUNT,
 | 
			
		||||
} from './constants';
 | 
			
		||||
import { getGeistInfoForPair } from './geist_utils';
 | 
			
		||||
import { getLiquidityProvidersForPair } from './liquidity_provider_utils';
 | 
			
		||||
import { getIntermediateTokens } from './multihop_utils';
 | 
			
		||||
import { BalancerPoolsCache, BalancerV2PoolsCache, CreamPoolsCache, PoolsCache } from './pools_cache';
 | 
			
		||||
import { BalancerV2SwapInfoCache } from './pools_cache/balancer_v2_utils_new';
 | 
			
		||||
import { SamplerContractOperation } from './sampler_contract_operation';
 | 
			
		||||
import { SamplerNoOperation } from './sampler_no_operation';
 | 
			
		||||
import { SourceFilters } from './source_filters';
 | 
			
		||||
@@ -58,6 +63,8 @@ import {
 | 
			
		||||
    AaveV2FillData,
 | 
			
		||||
    AaveV2Info,
 | 
			
		||||
    BalancerFillData,
 | 
			
		||||
    BalancerSwapInfo,
 | 
			
		||||
    BalancerV2BatchSwapFillData,
 | 
			
		||||
    BalancerV2FillData,
 | 
			
		||||
    BalancerV2PoolInfo,
 | 
			
		||||
    BancorFillData,
 | 
			
		||||
@@ -71,10 +78,9 @@ import {
 | 
			
		||||
    GeistFillData,
 | 
			
		||||
    GeistInfo,
 | 
			
		||||
    GenericRouterFillData,
 | 
			
		||||
    GMXFillData,
 | 
			
		||||
    HopInfo,
 | 
			
		||||
    KyberDmmFillData,
 | 
			
		||||
    KyberFillData,
 | 
			
		||||
    KyberSamplerOpts,
 | 
			
		||||
    LidoFillData,
 | 
			
		||||
    LidoInfo,
 | 
			
		||||
    LiquidityProviderFillData,
 | 
			
		||||
@@ -82,6 +88,7 @@ import {
 | 
			
		||||
    MakerPsmFillData,
 | 
			
		||||
    MooniswapFillData,
 | 
			
		||||
    MultiHopFillData,
 | 
			
		||||
    PlatypusFillData,
 | 
			
		||||
    PsmInfo,
 | 
			
		||||
    ShellFillData,
 | 
			
		||||
    SourceQuoteOperation,
 | 
			
		||||
@@ -89,6 +96,7 @@ import {
 | 
			
		||||
    TokenAdjacencyGraph,
 | 
			
		||||
    UniswapV2FillData,
 | 
			
		||||
    UniswapV3FillData,
 | 
			
		||||
    VelodromeFillData,
 | 
			
		||||
} from './types';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -103,6 +111,10 @@ export const TWO_HOP_SOURCE_FILTERS = SourceFilters.all().exclude([
 | 
			
		||||
 */
 | 
			
		||||
export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSource.MultiHop, ERC20BridgeSource.Native]);
 | 
			
		||||
 | 
			
		||||
export type PoolsCacheMap = { [key in Exclude<SourcesWithPoolsCache, ERC20BridgeSource.BalancerV2>]: PoolsCache } & {
 | 
			
		||||
    [ERC20BridgeSource.BalancerV2]: BalancerV2SwapInfoCache | undefined;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// tslint:disable:no-inferred-empty-object-type no-unbound-method
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -111,7 +123,7 @@ export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSour
 | 
			
		||||
 */
 | 
			
		||||
export class SamplerOperations {
 | 
			
		||||
    public readonly liquidityProviderRegistry: LiquidityProviderRegistry;
 | 
			
		||||
    public readonly poolsCaches: { [key in SourcesWithPoolsCache]: PoolsCache };
 | 
			
		||||
    public readonly poolsCaches: PoolsCacheMap;
 | 
			
		||||
    public readonly aaveReservesCache: AaveV2ReservesCache | undefined;
 | 
			
		||||
    public readonly compoundCTokenCache: CompoundCTokenCache | undefined;
 | 
			
		||||
    protected _bancorService?: BancorService;
 | 
			
		||||
@@ -126,7 +138,7 @@ export class SamplerOperations {
 | 
			
		||||
    constructor(
 | 
			
		||||
        public readonly chainId: ChainId,
 | 
			
		||||
        protected readonly _samplerContract: ERC20BridgeSamplerContract,
 | 
			
		||||
        poolsCaches?: { [key in SourcesWithPoolsCache]: PoolsCache },
 | 
			
		||||
        poolsCaches?: PoolsCacheMap,
 | 
			
		||||
        protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] },
 | 
			
		||||
        liquidityProviderRegistry: LiquidityProviderRegistry = {},
 | 
			
		||||
        bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
 | 
			
		||||
@@ -138,13 +150,16 @@ export class SamplerOperations {
 | 
			
		||||
        this.poolsCaches = poolsCaches
 | 
			
		||||
            ? poolsCaches
 | 
			
		||||
            : {
 | 
			
		||||
                  [ERC20BridgeSource.BalancerV2]: new BalancerV2PoolsCache(chainId),
 | 
			
		||||
                  [ERC20BridgeSource.Beethovenx]: new BalancerV2PoolsCache(
 | 
			
		||||
                      chainId,
 | 
			
		||||
                      BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN[chainId],
 | 
			
		||||
                  ),
 | 
			
		||||
                  [ERC20BridgeSource.Balancer]: new BalancerPoolsCache(),
 | 
			
		||||
                  [ERC20BridgeSource.Cream]: new CreamPoolsCache(),
 | 
			
		||||
                  [ERC20BridgeSource.BalancerV2]:
 | 
			
		||||
                      BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[chainId] === NULL_ADDRESS
 | 
			
		||||
                          ? undefined
 | 
			
		||||
                          : new BalancerV2SwapInfoCache(chainId),
 | 
			
		||||
              };
 | 
			
		||||
 | 
			
		||||
        const aaveSubgraphUrl = AAVE_V2_SUBGRAPH_URL_BY_CHAIN_ID[chainId];
 | 
			
		||||
@@ -250,54 +265,6 @@ export class SamplerOperations {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getKyberSellQuotes(
 | 
			
		||||
        kyberOpts: KyberSamplerOpts,
 | 
			
		||||
        reserveOffset: BigNumber,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Kyber,
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleSellsFromKyberNetwork,
 | 
			
		||||
            params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken, takerFillAmounts],
 | 
			
		||||
            callback: (callResults: string, fillData: KyberFillData): BigNumber[] => {
 | 
			
		||||
                const [reserveId, hint, samples] = this._samplerContract.getABIDecodedReturnData<
 | 
			
		||||
                    [string, string, BigNumber[]]
 | 
			
		||||
                >('sampleSellsFromKyberNetwork', callResults);
 | 
			
		||||
                fillData.hint = hint;
 | 
			
		||||
                fillData.reserveId = reserveId;
 | 
			
		||||
                fillData.networkProxy = kyberOpts.networkProxy;
 | 
			
		||||
                return isAllowedKyberReserveId(reserveId) ? samples : [];
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getKyberBuyQuotes(
 | 
			
		||||
        kyberOpts: KyberSamplerOpts,
 | 
			
		||||
        reserveOffset: BigNumber,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Kyber,
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleBuysFromKyberNetwork,
 | 
			
		||||
            params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken, makerFillAmounts],
 | 
			
		||||
            callback: (callResults: string, fillData: KyberFillData): BigNumber[] => {
 | 
			
		||||
                const [reserveId, hint, samples] = this._samplerContract.getABIDecodedReturnData<
 | 
			
		||||
                    [string, string, BigNumber[]]
 | 
			
		||||
                >('sampleBuysFromKyberNetwork', callResults);
 | 
			
		||||
                fillData.hint = hint;
 | 
			
		||||
                fillData.reserveId = reserveId;
 | 
			
		||||
                fillData.networkProxy = kyberOpts.networkProxy;
 | 
			
		||||
                return isAllowedKyberReserveId(reserveId) ? samples : [];
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getKyberDmmSellQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        tokenAddressPath: string[],
 | 
			
		||||
@@ -564,6 +531,49 @@ export class SamplerOperations {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getBalancerV2MultihopSellQuotes(
 | 
			
		||||
        vault: string,
 | 
			
		||||
        quoteSwaps: BalancerSwapInfo, // Should always be sell swap steps.
 | 
			
		||||
        fillSwaps: BalancerSwapInfo, // Should always be sell swap steps.
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
        source: ERC20BridgeSource,
 | 
			
		||||
    ): SourceQuoteOperation<BalancerV2BatchSwapFillData> {
 | 
			
		||||
        const quoteSwapSteps = quoteSwaps.swapSteps.map(s => ({
 | 
			
		||||
            ...s,
 | 
			
		||||
            assetInIndex: new BigNumber(s.assetInIndex),
 | 
			
		||||
            assetOutIndex: new BigNumber(s.assetOutIndex),
 | 
			
		||||
        }));
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source,
 | 
			
		||||
            fillData: { vault, swapSteps: fillSwaps.swapSteps, assets: fillSwaps.assets },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleMultihopSellsFromBalancerV2,
 | 
			
		||||
            params: [vault, quoteSwapSteps, quoteSwaps.assets, takerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getBalancerV2MultihopBuyQuotes(
 | 
			
		||||
        vault: string,
 | 
			
		||||
        quoteSwaps: BalancerSwapInfo, // Should always be buy swap steps.
 | 
			
		||||
        fillSwaps: BalancerSwapInfo, // Should always be a sell quote.
 | 
			
		||||
        makerFillAmounts: BigNumber[],
 | 
			
		||||
        source: ERC20BridgeSource,
 | 
			
		||||
    ): SourceQuoteOperation<BalancerV2BatchSwapFillData> {
 | 
			
		||||
        const quoteSwapSteps = quoteSwaps.swapSteps.map(s => ({
 | 
			
		||||
            ...s,
 | 
			
		||||
            assetInIndex: new BigNumber(s.assetInIndex),
 | 
			
		||||
            assetOutIndex: new BigNumber(s.assetOutIndex),
 | 
			
		||||
        }));
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source,
 | 
			
		||||
            // NOTE: fillData is set up for sells but quote function is set up for buys.
 | 
			
		||||
            fillData: { vault, swapSteps: fillSwaps.swapSteps, assets: fillSwaps.assets },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleMultihopBuysFromBalancerV2,
 | 
			
		||||
            params: [vault, quoteSwapSteps, quoteSwaps.assets, makerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getBalancerV2SellQuotes(
 | 
			
		||||
        poolInfo: BalancerV2PoolInfo,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
@@ -704,6 +714,36 @@ export class SamplerOperations {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getBancorV3SellQuotes(
 | 
			
		||||
        networkAddress: string,
 | 
			
		||||
        networkInfoAddress: string,
 | 
			
		||||
        path: string[],
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<BancorFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.BancorV3,
 | 
			
		||||
            fillData: { networkAddress, path },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleSellsFromBancorV3,
 | 
			
		||||
            params: [MAINNET_TOKENS.WETH, networkInfoAddress, path, takerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getBancorV3BuyQuotes(
 | 
			
		||||
        networkAddress: string,
 | 
			
		||||
        networkInfoAddress: string,
 | 
			
		||||
        path: string[],
 | 
			
		||||
        makerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<BancorFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.BancorV3,
 | 
			
		||||
            fillData: { networkAddress, path },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleBuysFromBancorV3,
 | 
			
		||||
            params: [MAINNET_TOKENS.WETH, networkInfoAddress, path, makerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getMooniswapSellQuotes(
 | 
			
		||||
        registry: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
@@ -1101,8 +1141,10 @@ export class SamplerOperations {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Lido,
 | 
			
		||||
            fillData: {
 | 
			
		||||
                makerToken,
 | 
			
		||||
                takerToken,
 | 
			
		||||
                stEthTokenAddress: lidoInfo.stEthToken,
 | 
			
		||||
                wstEthTokenAddress: lidoInfo.wstEthToken,
 | 
			
		||||
            },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleSellsFromLido,
 | 
			
		||||
@@ -1119,8 +1161,10 @@ export class SamplerOperations {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Lido,
 | 
			
		||||
            fillData: {
 | 
			
		||||
                makerToken,
 | 
			
		||||
                takerToken,
 | 
			
		||||
                stEthTokenAddress: lidoInfo.stEthToken,
 | 
			
		||||
                wstEthTokenAddress: lidoInfo.wstEthToken,
 | 
			
		||||
            },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleBuysFromLido,
 | 
			
		||||
@@ -1214,6 +1258,113 @@ export class SamplerOperations {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getGMXSellQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        reader: string,
 | 
			
		||||
        vault: string,
 | 
			
		||||
        tokenAddressPath: string[],
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<GMXFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.GMX,
 | 
			
		||||
            fillData: { router, reader, vault, tokenAddressPath },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleSellsFromGMX,
 | 
			
		||||
            params: [reader, vault, tokenAddressPath, takerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    public getGMXBuyQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        reader: string,
 | 
			
		||||
        vault: string,
 | 
			
		||||
        tokenAddressPath: string[],
 | 
			
		||||
        makerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<GMXFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.GMX,
 | 
			
		||||
            fillData: { router, reader, vault, tokenAddressPath },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleBuysFromGMX,
 | 
			
		||||
            params: [reader, vault, tokenAddressPath, makerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getPlatypusSellQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        pool: string[],
 | 
			
		||||
        tokenAddressPath: string[],
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<PlatypusFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Platypus,
 | 
			
		||||
            fillData: { router, pool, tokenAddressPath },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleSellsFromPlatypus,
 | 
			
		||||
            params: [pool[0], tokenAddressPath, takerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getPlatypusBuyQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        pool: string[],
 | 
			
		||||
        tokenAddressPath: string[],
 | 
			
		||||
        makerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<PlatypusFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Platypus,
 | 
			
		||||
            fillData: { router, pool, tokenAddressPath },
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleBuysFromPlatypus,
 | 
			
		||||
            params: [pool[0], tokenAddressPath, makerFillAmounts],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getVelodromeSellQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<VelodromeFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Velodrome,
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleSellsFromVelodrome,
 | 
			
		||||
            params: [router, takerToken, makerToken, takerFillAmounts],
 | 
			
		||||
            callback: (callResults: string, fillData: VelodromeFillData): BigNumber[] => {
 | 
			
		||||
                const [isStable, samples] = this._samplerContract.getABIDecodedReturnData<[boolean, BigNumber[]]>(
 | 
			
		||||
                    'sampleSellsFromVelodrome',
 | 
			
		||||
                    callResults,
 | 
			
		||||
                );
 | 
			
		||||
                fillData.router = router;
 | 
			
		||||
                fillData.stable = isStable;
 | 
			
		||||
                return samples;
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getVelodromeBuyQuotes(
 | 
			
		||||
        router: string,
 | 
			
		||||
        takerToken: string,
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
        makerFillAmounts: BigNumber[],
 | 
			
		||||
    ): SourceQuoteOperation<VelodromeFillData> {
 | 
			
		||||
        return new SamplerContractOperation({
 | 
			
		||||
            source: ERC20BridgeSource.Velodrome,
 | 
			
		||||
            contract: this._samplerContract,
 | 
			
		||||
            function: this._samplerContract.sampleBuysFromVelodrome,
 | 
			
		||||
            params: [router, takerToken, makerToken, makerFillAmounts],
 | 
			
		||||
            callback: (callResults: string, fillData: VelodromeFillData): BigNumber[] => {
 | 
			
		||||
                const [isStable, samples] = this._samplerContract.getABIDecodedReturnData<[boolean, BigNumber[]]>(
 | 
			
		||||
                    'sampleBuysFromVelodrome',
 | 
			
		||||
                    callResults,
 | 
			
		||||
                );
 | 
			
		||||
                fillData.router = router;
 | 
			
		||||
                fillData.stable = isStable;
 | 
			
		||||
                return samples;
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public getMedianSellRate(
 | 
			
		||||
        sources: ERC20BridgeSource[],
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
@@ -1299,7 +1450,7 @@ export class SamplerOperations {
 | 
			
		||||
        takerFillAmounts: BigNumber[],
 | 
			
		||||
        tokenAdjacencyGraph: TokenAdjacencyGraph = this.tokenAdjacencyGraph,
 | 
			
		||||
    ): SourceQuoteOperation[] {
 | 
			
		||||
        // Find the adjacent tokens in the provided tooken adjacency graph,
 | 
			
		||||
        // Find the adjacent tokens in the provided token adjacency graph,
 | 
			
		||||
        // e.g if this is DAI->USDC we may check for DAI->WETH->USDC
 | 
			
		||||
        const intermediateTokens = getIntermediateTokens(makerToken, takerToken, tokenAdjacencyGraph);
 | 
			
		||||
        // Drop out MultiHop and Native as we do not query those here.
 | 
			
		||||
@@ -1312,8 +1463,6 @@ export class SamplerOperations {
 | 
			
		||||
                    return [];
 | 
			
		||||
                }
 | 
			
		||||
                switch (source) {
 | 
			
		||||
                    case ERC20BridgeSource.Eth2Dai:
 | 
			
		||||
                        return [];
 | 
			
		||||
                    case ERC20BridgeSource.Uniswap:
 | 
			
		||||
                        return isValidAddress(UNISWAPV1_ROUTER_BY_CHAIN_ID[this.chainId])
 | 
			
		||||
                            ? this.getUniswapSellQuotes(
 | 
			
		||||
@@ -1330,22 +1479,23 @@ export class SamplerOperations {
 | 
			
		||||
                    case ERC20BridgeSource.PancakeSwapV2:
 | 
			
		||||
                    case ERC20BridgeSource.BakerySwap:
 | 
			
		||||
                    case ERC20BridgeSource.ApeSwap:
 | 
			
		||||
                    case ERC20BridgeSource.CafeSwap:
 | 
			
		||||
                    case ERC20BridgeSource.CheeseSwap:
 | 
			
		||||
                    case ERC20BridgeSource.JulSwap:
 | 
			
		||||
                    case ERC20BridgeSource.QuickSwap:
 | 
			
		||||
                    case ERC20BridgeSource.ComethSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Dfyn:
 | 
			
		||||
                    case ERC20BridgeSource.WaultSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Polydex:
 | 
			
		||||
                    case ERC20BridgeSource.ShibaSwap:
 | 
			
		||||
                    case ERC20BridgeSource.JetSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Pangolin:
 | 
			
		||||
                    case ERC20BridgeSource.TraderJoe:
 | 
			
		||||
                    case ERC20BridgeSource.UbeSwap:
 | 
			
		||||
                    case ERC20BridgeSource.SpiritSwap:
 | 
			
		||||
                    case ERC20BridgeSource.SpookySwap:
 | 
			
		||||
                    case ERC20BridgeSource.Yoshi:
 | 
			
		||||
                    case ERC20BridgeSource.MorpheusSwap:
 | 
			
		||||
                    case ERC20BridgeSource.BiSwap:
 | 
			
		||||
                    case ERC20BridgeSource.MDex:
 | 
			
		||||
                    case ERC20BridgeSource.KnightSwap:
 | 
			
		||||
                    case ERC20BridgeSource.MeshSwap:
 | 
			
		||||
                        const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
 | 
			
		||||
                        if (!isValidAddress(uniLikeRouter)) {
 | 
			
		||||
                            return [];
 | 
			
		||||
@@ -1360,20 +1510,8 @@ export class SamplerOperations {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        return this.getKyberDmmSellQuotes(kyberDmmRouter, [takerToken, makerToken], takerFillAmounts);
 | 
			
		||||
                    case ERC20BridgeSource.Kyber:
 | 
			
		||||
                        return getKyberOffsets().map(offset =>
 | 
			
		||||
                            this.getKyberSellQuotes(
 | 
			
		||||
                                KYBER_CONFIG_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                                offset,
 | 
			
		||||
                                makerToken,
 | 
			
		||||
                                takerToken,
 | 
			
		||||
                                takerFillAmounts,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.Curve:
 | 
			
		||||
                    case ERC20BridgeSource.CurveV2:
 | 
			
		||||
                    case ERC20BridgeSource.Swerve:
 | 
			
		||||
                    case ERC20BridgeSource.SnowSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Nerve:
 | 
			
		||||
                    case ERC20BridgeSource.Synapse:
 | 
			
		||||
                    case ERC20BridgeSource.Belt:
 | 
			
		||||
@@ -1383,6 +1521,7 @@ export class SamplerOperations {
 | 
			
		||||
                    case ERC20BridgeSource.FirebirdOneSwap:
 | 
			
		||||
                    case ERC20BridgeSource.IronSwap:
 | 
			
		||||
                    case ERC20BridgeSource.ACryptos:
 | 
			
		||||
                    case ERC20BridgeSource.MobiusMoney:
 | 
			
		||||
                        return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
 | 
			
		||||
                            this.getCurveSellQuotes(
 | 
			
		||||
                                pool,
 | 
			
		||||
@@ -1447,15 +1586,27 @@ export class SamplerOperations {
 | 
			
		||||
                                ERC20BridgeSource.Balancer,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.BalancerV2:
 | 
			
		||||
                    case ERC20BridgeSource.Beethovenx:
 | 
			
		||||
                    case ERC20BridgeSource.BalancerV2: {
 | 
			
		||||
                        const cache = this.poolsCaches[source];
 | 
			
		||||
                        if (!cache) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        const swaps = cache.getCachedSwapInfoForPair(takerToken, makerToken);
 | 
			
		||||
                        const vault = BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId];
 | 
			
		||||
                        if (!swaps || vault === NULL_ADDRESS) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        // Changed to retrieve queryBatchSwap for swap steps > 1 of length
 | 
			
		||||
                        return swaps.swapInfoExactIn.map(swapInfo =>
 | 
			
		||||
                            this.getBalancerV2MultihopSellQuotes(vault, swapInfo, swapInfo, takerFillAmounts, source),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Beethovenx: {
 | 
			
		||||
                        const poolIds =
 | 
			
		||||
                            this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
 | 
			
		||||
 | 
			
		||||
                        const vault =
 | 
			
		||||
                            source === ERC20BridgeSource.BalancerV2
 | 
			
		||||
                                ? BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId]
 | 
			
		||||
                                : BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
 | 
			
		||||
                        const vault = BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
 | 
			
		||||
                        if (vault === NULL_ADDRESS) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
@@ -1468,6 +1619,7 @@ export class SamplerOperations {
 | 
			
		||||
                                source,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Cream:
 | 
			
		||||
                        return (
 | 
			
		||||
                            this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
 | 
			
		||||
@@ -1519,23 +1671,6 @@ export class SamplerOperations {
 | 
			
		||||
                            takerToken,
 | 
			
		||||
                            takerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.Linkswap:
 | 
			
		||||
                        if (!isValidAddress(LINKSWAP_ROUTER_BY_CHAIN_ID[this.chainId])) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        return [
 | 
			
		||||
                            [takerToken, makerToken],
 | 
			
		||||
                            ...getIntermediateTokens(makerToken, takerToken, {
 | 
			
		||||
                                default: [MAINNET_TOKENS.LINK, MAINNET_TOKENS.WETH],
 | 
			
		||||
                            }).map(t => [takerToken, t, makerToken]),
 | 
			
		||||
                        ].map(path =>
 | 
			
		||||
                            this.getUniswapV2SellQuotes(
 | 
			
		||||
                                LINKSWAP_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                                path,
 | 
			
		||||
                                takerFillAmounts,
 | 
			
		||||
                                ERC20BridgeSource.Linkswap,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.MakerPsm:
 | 
			
		||||
                        const psmInfo = MAKER_PSM_INFO_BY_CHAIN_ID[this.chainId];
 | 
			
		||||
                        if (!isValidAddress(psmInfo.psmAddress)) {
 | 
			
		||||
@@ -1553,16 +1688,10 @@ export class SamplerOperations {
 | 
			
		||||
                        ].map(path => this.getUniswapV3SellQuotes(router, quoter, path, takerFillAmounts));
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Lido: {
 | 
			
		||||
                        const lidoInfo = LIDO_INFO_BY_CHAIN[this.chainId];
 | 
			
		||||
                        if (
 | 
			
		||||
                            lidoInfo.stEthToken === NULL_ADDRESS ||
 | 
			
		||||
                            lidoInfo.wethToken === NULL_ADDRESS ||
 | 
			
		||||
                            takerToken.toLowerCase() !== lidoInfo.wethToken.toLowerCase() ||
 | 
			
		||||
                            makerToken.toLowerCase() !== lidoInfo.stEthToken.toLowerCase()
 | 
			
		||||
                        ) {
 | 
			
		||||
                        if (!this._isLidoSupported(takerToken, makerToken)) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        const lidoInfo = LIDO_INFO_BY_CHAIN[this.chainId];
 | 
			
		||||
                        return this.getLidoSellQuotes(lidoInfo, makerToken, takerToken, takerFillAmounts);
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.AaveV2: {
 | 
			
		||||
@@ -1604,6 +1733,45 @@ export class SamplerOperations {
 | 
			
		||||
                            takerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.GMX: {
 | 
			
		||||
                        // low liquidity mim pool dont quote
 | 
			
		||||
                        if (takerToken === AVALANCHE_TOKENS.MIM || makerToken === 'AVALANCHE_TOKENS.MIM') {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        return this.getGMXSellQuotes(
 | 
			
		||||
                            GMX_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            GMX_READER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            GMX_VAULT_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            [takerToken, makerToken],
 | 
			
		||||
                            takerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Platypus: {
 | 
			
		||||
                        return getPlatypusInfoForPair(this.chainId, takerToken, makerToken).map(pool =>
 | 
			
		||||
                            this.getPlatypusSellQuotes(
 | 
			
		||||
                                PLATYPUS_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                                [pool.poolAddress],
 | 
			
		||||
                                [takerToken, makerToken],
 | 
			
		||||
                                takerFillAmounts,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.BancorV3: {
 | 
			
		||||
                        return this.getBancorV3SellQuotes(
 | 
			
		||||
                            BANCORV3_NETWORK_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            BANCORV3_NETWORK_INFO_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            [takerToken, makerToken],
 | 
			
		||||
                            takerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Velodrome: {
 | 
			
		||||
                        return this.getVelodromeSellQuotes(
 | 
			
		||||
                            VELODROME_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            takerToken,
 | 
			
		||||
                            makerToken,
 | 
			
		||||
                            takerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    default:
 | 
			
		||||
                        throw new Error(`Unsupported sell sample source: ${source}`);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1612,6 +1780,24 @@ export class SamplerOperations {
 | 
			
		||||
        return allOps;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _isLidoSupported(takerTokenAddress: string, makerTokenAddress: string): boolean {
 | 
			
		||||
        const lidoInfo = LIDO_INFO_BY_CHAIN[this.chainId];
 | 
			
		||||
        if (lidoInfo.wethToken === NULL_ADDRESS) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        const takerToken = takerTokenAddress.toLowerCase();
 | 
			
		||||
        const makerToken = makerTokenAddress.toLowerCase();
 | 
			
		||||
        const wethToken = lidoInfo.wethToken.toLowerCase();
 | 
			
		||||
        const stEthToken = lidoInfo.stEthToken.toLowerCase();
 | 
			
		||||
        const wstEthToken = lidoInfo.wstEthToken.toLowerCase();
 | 
			
		||||
 | 
			
		||||
        if (takerToken === wethToken && makerToken === stEthToken) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return _.difference([stEthToken, wstEthToken], [takerToken, makerToken]).length === 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private _getBuyQuoteOperations(
 | 
			
		||||
        sources: ERC20BridgeSource[],
 | 
			
		||||
        makerToken: string,
 | 
			
		||||
@@ -1625,8 +1811,6 @@ export class SamplerOperations {
 | 
			
		||||
        return _.flatten(
 | 
			
		||||
            _sources.map((source): SourceQuoteOperation | SourceQuoteOperation[] => {
 | 
			
		||||
                switch (source) {
 | 
			
		||||
                    case ERC20BridgeSource.Eth2Dai:
 | 
			
		||||
                        return [];
 | 
			
		||||
                    case ERC20BridgeSource.Uniswap:
 | 
			
		||||
                        return isValidAddress(UNISWAPV1_ROUTER_BY_CHAIN_ID[this.chainId])
 | 
			
		||||
                            ? this.getUniswapBuyQuotes(
 | 
			
		||||
@@ -1643,22 +1827,23 @@ export class SamplerOperations {
 | 
			
		||||
                    case ERC20BridgeSource.PancakeSwapV2:
 | 
			
		||||
                    case ERC20BridgeSource.BakerySwap:
 | 
			
		||||
                    case ERC20BridgeSource.ApeSwap:
 | 
			
		||||
                    case ERC20BridgeSource.CafeSwap:
 | 
			
		||||
                    case ERC20BridgeSource.CheeseSwap:
 | 
			
		||||
                    case ERC20BridgeSource.JulSwap:
 | 
			
		||||
                    case ERC20BridgeSource.QuickSwap:
 | 
			
		||||
                    case ERC20BridgeSource.ComethSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Dfyn:
 | 
			
		||||
                    case ERC20BridgeSource.WaultSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Polydex:
 | 
			
		||||
                    case ERC20BridgeSource.ShibaSwap:
 | 
			
		||||
                    case ERC20BridgeSource.JetSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Pangolin:
 | 
			
		||||
                    case ERC20BridgeSource.TraderJoe:
 | 
			
		||||
                    case ERC20BridgeSource.UbeSwap:
 | 
			
		||||
                    case ERC20BridgeSource.SpiritSwap:
 | 
			
		||||
                    case ERC20BridgeSource.SpookySwap:
 | 
			
		||||
                    case ERC20BridgeSource.Yoshi:
 | 
			
		||||
                    case ERC20BridgeSource.MorpheusSwap:
 | 
			
		||||
                    case ERC20BridgeSource.BiSwap:
 | 
			
		||||
                    case ERC20BridgeSource.MDex:
 | 
			
		||||
                    case ERC20BridgeSource.KnightSwap:
 | 
			
		||||
                    case ERC20BridgeSource.MeshSwap:
 | 
			
		||||
                        const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
 | 
			
		||||
                        if (!isValidAddress(uniLikeRouter)) {
 | 
			
		||||
                            return [];
 | 
			
		||||
@@ -1673,20 +1858,8 @@ export class SamplerOperations {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        return this.getKyberDmmBuyQuotes(kyberDmmRouter, [takerToken, makerToken], makerFillAmounts);
 | 
			
		||||
                    case ERC20BridgeSource.Kyber:
 | 
			
		||||
                        return getKyberOffsets().map(offset =>
 | 
			
		||||
                            this.getKyberBuyQuotes(
 | 
			
		||||
                                KYBER_CONFIG_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                                offset,
 | 
			
		||||
                                makerToken,
 | 
			
		||||
                                takerToken,
 | 
			
		||||
                                makerFillAmounts,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.Curve:
 | 
			
		||||
                    case ERC20BridgeSource.CurveV2:
 | 
			
		||||
                    case ERC20BridgeSource.Swerve:
 | 
			
		||||
                    case ERC20BridgeSource.SnowSwap:
 | 
			
		||||
                    case ERC20BridgeSource.Nerve:
 | 
			
		||||
                    case ERC20BridgeSource.Synapse:
 | 
			
		||||
                    case ERC20BridgeSource.Belt:
 | 
			
		||||
@@ -1696,6 +1869,7 @@ export class SamplerOperations {
 | 
			
		||||
                    case ERC20BridgeSource.FirebirdOneSwap:
 | 
			
		||||
                    case ERC20BridgeSource.IronSwap:
 | 
			
		||||
                    case ERC20BridgeSource.ACryptos:
 | 
			
		||||
                    case ERC20BridgeSource.MobiusMoney:
 | 
			
		||||
                        return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
 | 
			
		||||
                            this.getCurveBuyQuotes(
 | 
			
		||||
                                pool,
 | 
			
		||||
@@ -1760,15 +1934,33 @@ export class SamplerOperations {
 | 
			
		||||
                                ERC20BridgeSource.Balancer,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.BalancerV2:
 | 
			
		||||
                    case ERC20BridgeSource.Beethovenx:
 | 
			
		||||
                    case ERC20BridgeSource.BalancerV2: {
 | 
			
		||||
                        const cache = this.poolsCaches[source];
 | 
			
		||||
                        if (!cache) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        const swaps = cache.getCachedSwapInfoForPair(takerToken, makerToken);
 | 
			
		||||
                        const vault = BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId];
 | 
			
		||||
                        if (!swaps || vault === NULL_ADDRESS) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        // Changed to retrieve queryBatchSwap for swap steps > 1 of length
 | 
			
		||||
                        return swaps.swapInfoExactOut.map((quoteSwapInfo, i) =>
 | 
			
		||||
                            this.getBalancerV2MultihopBuyQuotes(
 | 
			
		||||
                                vault,
 | 
			
		||||
                                quoteSwapInfo,
 | 
			
		||||
                                swaps.swapInfoExactIn[i],
 | 
			
		||||
                                makerFillAmounts,
 | 
			
		||||
                                source,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Beethovenx: {
 | 
			
		||||
                        const poolIds =
 | 
			
		||||
                            this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
 | 
			
		||||
 | 
			
		||||
                        const vault =
 | 
			
		||||
                            source === ERC20BridgeSource.BalancerV2
 | 
			
		||||
                                ? BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId]
 | 
			
		||||
                                : BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
 | 
			
		||||
                        const vault = BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
 | 
			
		||||
                        if (vault === NULL_ADDRESS) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
@@ -1781,6 +1973,7 @@ export class SamplerOperations {
 | 
			
		||||
                                source,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Cream:
 | 
			
		||||
                        return (
 | 
			
		||||
                            this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
 | 
			
		||||
@@ -1826,24 +2019,6 @@ export class SamplerOperations {
 | 
			
		||||
                        // Unimplemented
 | 
			
		||||
                        // return this.getBancorBuyQuotes(makerToken, takerToken, makerFillAmounts);
 | 
			
		||||
                        return [];
 | 
			
		||||
                    case ERC20BridgeSource.Linkswap:
 | 
			
		||||
                        if (!isValidAddress(LINKSWAP_ROUTER_BY_CHAIN_ID[this.chainId])) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        return [
 | 
			
		||||
                            [takerToken, makerToken],
 | 
			
		||||
                            // LINK is the base asset in many of the pools on Linkswap
 | 
			
		||||
                            ...getIntermediateTokens(makerToken, takerToken, {
 | 
			
		||||
                                default: [MAINNET_TOKENS.LINK, MAINNET_TOKENS.WETH],
 | 
			
		||||
                            }).map(t => [takerToken, t, makerToken]),
 | 
			
		||||
                        ].map(path =>
 | 
			
		||||
                            this.getUniswapV2BuyQuotes(
 | 
			
		||||
                                LINKSWAP_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                                path,
 | 
			
		||||
                                makerFillAmounts,
 | 
			
		||||
                                ERC20BridgeSource.Linkswap,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    case ERC20BridgeSource.MakerPsm:
 | 
			
		||||
                        const psmInfo = MAKER_PSM_INFO_BY_CHAIN_ID[this.chainId];
 | 
			
		||||
                        if (!isValidAddress(psmInfo.psmAddress)) {
 | 
			
		||||
@@ -1861,17 +2036,10 @@ export class SamplerOperations {
 | 
			
		||||
                        ].map(path => this.getUniswapV3BuyQuotes(router, quoter, path, makerFillAmounts));
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Lido: {
 | 
			
		||||
                        const lidoInfo = LIDO_INFO_BY_CHAIN[this.chainId];
 | 
			
		||||
 | 
			
		||||
                        if (
 | 
			
		||||
                            lidoInfo.stEthToken === NULL_ADDRESS ||
 | 
			
		||||
                            lidoInfo.wethToken === NULL_ADDRESS ||
 | 
			
		||||
                            takerToken.toLowerCase() !== lidoInfo.wethToken.toLowerCase() ||
 | 
			
		||||
                            makerToken.toLowerCase() !== lidoInfo.stEthToken.toLowerCase()
 | 
			
		||||
                        ) {
 | 
			
		||||
                        if (!this._isLidoSupported(takerToken, makerToken)) {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        const lidoInfo = LIDO_INFO_BY_CHAIN[this.chainId];
 | 
			
		||||
                        return this.getLidoBuyQuotes(lidoInfo, makerToken, takerToken, makerFillAmounts);
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.AaveV2: {
 | 
			
		||||
@@ -1907,6 +2075,45 @@ export class SamplerOperations {
 | 
			
		||||
                        }
 | 
			
		||||
                        return this.getCompoundBuyQuotes(cToken.tokenAddress, makerToken, takerToken, makerFillAmounts);
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.GMX: {
 | 
			
		||||
                        // bad mim pool dont quote
 | 
			
		||||
                        if (takerToken === 'AVALANCHE_TOKENS.MIM' || makerToken === 'AVALANCHE_TOKENS.MIM') {
 | 
			
		||||
                            return [];
 | 
			
		||||
                        }
 | 
			
		||||
                        return this.getGMXBuyQuotes(
 | 
			
		||||
                            GMX_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            GMX_READER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            GMX_VAULT_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            [takerToken, makerToken],
 | 
			
		||||
                            makerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Platypus: {
 | 
			
		||||
                        return getPlatypusInfoForPair(this.chainId, takerToken, makerToken).map(pool =>
 | 
			
		||||
                            this.getPlatypusBuyQuotes(
 | 
			
		||||
                                PLATYPUS_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                                [pool.poolAddress],
 | 
			
		||||
                                [takerToken, makerToken],
 | 
			
		||||
                                makerFillAmounts,
 | 
			
		||||
                            ),
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.BancorV3: {
 | 
			
		||||
                        return this.getBancorV3BuyQuotes(
 | 
			
		||||
                            BANCORV3_NETWORK_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            BANCORV3_NETWORK_INFO_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            [takerToken, makerToken],
 | 
			
		||||
                            makerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    case ERC20BridgeSource.Velodrome: {
 | 
			
		||||
                        return this.getVelodromeBuyQuotes(
 | 
			
		||||
                            VELODROME_ROUTER_BY_CHAIN_ID[this.chainId],
 | 
			
		||||
                            takerToken,
 | 
			
		||||
                            makerToken,
 | 
			
		||||
                            makerFillAmounts,
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    default:
 | 
			
		||||
                        throw new Error(`Unsupported buy sample source: ${source}`);
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import { BigNumber } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts } from '../../types';
 | 
			
		||||
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor';
 | 
			
		||||
import { IRfqClient } from '../irfq_client';
 | 
			
		||||
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator';
 | 
			
		||||
 | 
			
		||||
import { SourceFilters } from './source_filters';
 | 
			
		||||
@@ -37,8 +38,6 @@ export enum ERC20BridgeSource {
 | 
			
		||||
    Native = 'Native',
 | 
			
		||||
    Uniswap = 'Uniswap',
 | 
			
		||||
    UniswapV2 = 'Uniswap_V2',
 | 
			
		||||
    Eth2Dai = 'Eth2Dai',
 | 
			
		||||
    Kyber = 'Kyber',
 | 
			
		||||
    Curve = 'Curve',
 | 
			
		||||
    LiquidityProvider = 'LiquidityProvider',
 | 
			
		||||
    MultiBridge = 'MultiBridge',
 | 
			
		||||
@@ -51,13 +50,10 @@ export enum ERC20BridgeSource {
 | 
			
		||||
    Mooniswap = 'Mooniswap',
 | 
			
		||||
    MultiHop = 'MultiHop',
 | 
			
		||||
    Shell = 'Shell',
 | 
			
		||||
    Swerve = 'Swerve',
 | 
			
		||||
    SnowSwap = 'SnowSwap',
 | 
			
		||||
    SushiSwap = 'SushiSwap',
 | 
			
		||||
    Dodo = 'DODO',
 | 
			
		||||
    DodoV2 = 'DODO_V2',
 | 
			
		||||
    CryptoCom = 'CryptoCom',
 | 
			
		||||
    Linkswap = 'Linkswap',
 | 
			
		||||
    KyberDmm = 'KyberDMM',
 | 
			
		||||
    Smoothy = 'Smoothy',
 | 
			
		||||
    Component = 'Component',
 | 
			
		||||
@@ -70,38 +66,46 @@ export enum ERC20BridgeSource {
 | 
			
		||||
    AaveV2 = 'Aave_V2',
 | 
			
		||||
    Compound = 'Compound',
 | 
			
		||||
    Synapse = 'Synapse',
 | 
			
		||||
    BancorV3 = 'BancorV3',
 | 
			
		||||
    // BSC only
 | 
			
		||||
    PancakeSwap = 'PancakeSwap',
 | 
			
		||||
    PancakeSwapV2 = 'PancakeSwap_V2',
 | 
			
		||||
    BiSwap = 'BiSwap',
 | 
			
		||||
    MDex = 'MDex',
 | 
			
		||||
    KnightSwap = 'KnightSwap',
 | 
			
		||||
    BakerySwap = 'BakerySwap',
 | 
			
		||||
    Nerve = 'Nerve',
 | 
			
		||||
    Belt = 'Belt',
 | 
			
		||||
    Ellipsis = 'Ellipsis',
 | 
			
		||||
    ApeSwap = 'ApeSwap',
 | 
			
		||||
    CafeSwap = 'CafeSwap',
 | 
			
		||||
    CheeseSwap = 'CheeseSwap',
 | 
			
		||||
    JulSwap = 'JulSwap',
 | 
			
		||||
    ACryptos = 'ACryptoS',
 | 
			
		||||
    // Polygon only
 | 
			
		||||
    QuickSwap = 'QuickSwap',
 | 
			
		||||
    ComethSwap = 'ComethSwap',
 | 
			
		||||
    Dfyn = 'Dfyn',
 | 
			
		||||
    WaultSwap = 'WaultSwap',
 | 
			
		||||
    Polydex = 'Polydex',
 | 
			
		||||
    FirebirdOneSwap = 'FirebirdOneSwap',
 | 
			
		||||
    JetSwap = 'JetSwap',
 | 
			
		||||
    IronSwap = 'IronSwap',
 | 
			
		||||
    MeshSwap = 'MeshSwap',
 | 
			
		||||
    // Avalanche
 | 
			
		||||
    Pangolin = 'Pangolin',
 | 
			
		||||
    TraderJoe = 'TraderJoe',
 | 
			
		||||
    Platypus = 'Platypus',
 | 
			
		||||
    // tslint:disable: enum-naming
 | 
			
		||||
    GMX = 'GMX',
 | 
			
		||||
    // Celo only
 | 
			
		||||
    UbeSwap = 'UbeSwap',
 | 
			
		||||
    MobiusMoney = 'MobiusMoney',
 | 
			
		||||
    // Fantom
 | 
			
		||||
    SpiritSwap = 'SpiritSwap',
 | 
			
		||||
    SpookySwap = 'SpookySwap',
 | 
			
		||||
    Beethovenx = 'Beethovenx',
 | 
			
		||||
    MorpheusSwap = 'MorpheusSwap',
 | 
			
		||||
    Yoshi = 'Yoshi',
 | 
			
		||||
    Geist = 'Geist',
 | 
			
		||||
    // Optimism
 | 
			
		||||
    Velodrome = 'Velodrome',
 | 
			
		||||
}
 | 
			
		||||
export type SourcesWithPoolsCache =
 | 
			
		||||
    | ERC20BridgeSource.Balancer
 | 
			
		||||
@@ -165,6 +169,7 @@ export interface PsmInfo {
 | 
			
		||||
export interface LidoInfo {
 | 
			
		||||
    stEthToken: string;
 | 
			
		||||
    wethToken: string;
 | 
			
		||||
    wstEthToken: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -208,6 +213,23 @@ export interface CurveFillData extends FillData {
 | 
			
		||||
    pool: CurveInfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BalancerBatchSwapStep {
 | 
			
		||||
    poolId: string;
 | 
			
		||||
    assetInIndex: number;
 | 
			
		||||
    assetOutIndex: number;
 | 
			
		||||
    amount: BigNumber;
 | 
			
		||||
    userData: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BalancerSwaps {
 | 
			
		||||
    swapInfoExactIn: BalancerSwapInfo[];
 | 
			
		||||
    swapInfoExactOut: BalancerSwapInfo[];
 | 
			
		||||
}
 | 
			
		||||
export interface BalancerSwapInfo {
 | 
			
		||||
    assets: string[];
 | 
			
		||||
    swapSteps: BalancerBatchSwapStep[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BalancerFillData extends FillData {
 | 
			
		||||
    poolAddress: string;
 | 
			
		||||
}
 | 
			
		||||
@@ -217,6 +239,12 @@ export interface BalancerV2FillData extends FillData {
 | 
			
		||||
    poolId: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BalancerV2BatchSwapFillData extends FillData {
 | 
			
		||||
    vault: string;
 | 
			
		||||
    swapSteps: BalancerBatchSwapStep[];
 | 
			
		||||
    assets: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface UniswapV2FillData extends FillData {
 | 
			
		||||
    tokenAddressPath: string[];
 | 
			
		||||
    router: string;
 | 
			
		||||
@@ -236,10 +264,9 @@ export interface BancorFillData extends FillData {
 | 
			
		||||
    networkAddress: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface KyberFillData extends FillData {
 | 
			
		||||
    hint: string;
 | 
			
		||||
    reserveId: string;
 | 
			
		||||
    networkProxy: string;
 | 
			
		||||
export interface BancorV3FillData extends FillData {
 | 
			
		||||
    path: string[];
 | 
			
		||||
    networkAddress: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface MooniswapFillData extends FillData {
 | 
			
		||||
@@ -306,7 +333,9 @@ export interface FinalUniswapV3FillData extends Omit<UniswapV3FillData, 'pathAmo
 | 
			
		||||
 | 
			
		||||
export interface LidoFillData extends FillData {
 | 
			
		||||
    stEthTokenAddress: string;
 | 
			
		||||
    wstEthTokenAddress: string;
 | 
			
		||||
    takerToken: string;
 | 
			
		||||
    makerToken: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface AaveV2FillData extends FillData {
 | 
			
		||||
@@ -329,6 +358,30 @@ export interface GeistFillData extends FillData {
 | 
			
		||||
    takerToken: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PlatypusInfo {
 | 
			
		||||
    poolAddress: string;
 | 
			
		||||
    tokens: string[];
 | 
			
		||||
    gasSchedule: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface GMXFillData extends FillData {
 | 
			
		||||
    router: string;
 | 
			
		||||
    reader: string;
 | 
			
		||||
    vault: string;
 | 
			
		||||
    tokenAddressPath: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PlatypusFillData extends FillData {
 | 
			
		||||
    router: string;
 | 
			
		||||
    pool: string[];
 | 
			
		||||
    tokenAddressPath: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface VelodromeFillData extends FillData {
 | 
			
		||||
    router: string;
 | 
			
		||||
    stable: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a node on a fill path.
 | 
			
		||||
 */
 | 
			
		||||
@@ -348,7 +401,7 @@ export interface Fill<TFillData extends FillData = FillData> {
 | 
			
		||||
    input: BigNumber;
 | 
			
		||||
    // Output fill amount (maker asset amount in a sell, taker asset amount in a buy).
 | 
			
		||||
    output: BigNumber;
 | 
			
		||||
    // The output fill amount, ajdusted by fees.
 | 
			
		||||
    // The output fill amount, adjusted by fees.
 | 
			
		||||
    adjustedOutput: BigNumber;
 | 
			
		||||
    // Fill that must precede this one. This enforces certain fills to be contiguous.
 | 
			
		||||
    parent?: Fill;
 | 
			
		||||
@@ -426,6 +479,7 @@ export type OptimizedMarketOrder =
 | 
			
		||||
    | OptimizedMarketOrderBase<NativeRfqOrderFillData>;
 | 
			
		||||
 | 
			
		||||
export interface GetMarketOrdersRfqOpts extends RfqRequestOpts {
 | 
			
		||||
    rfqClient?: IRfqClient;
 | 
			
		||||
    quoteRequestor?: QuoteRequestor;
 | 
			
		||||
    firmQuoteValidator?: RfqFirmQuoteValidator;
 | 
			
		||||
}
 | 
			
		||||
@@ -609,6 +663,7 @@ export interface MarketSideLiquidity {
 | 
			
		||||
    takerTokenDecimals: number;
 | 
			
		||||
    quotes: RawQuotes;
 | 
			
		||||
    isRfqSupported: boolean;
 | 
			
		||||
    blockNumber: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface RawQuotes {
 | 
			
		||||
@@ -647,9 +702,3 @@ export interface GenerateOptimizedOrdersOpts {
 | 
			
		||||
export interface ComparisonPrice {
 | 
			
		||||
    wholeOrder: BigNumber | undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface KyberSamplerOpts {
 | 
			
		||||
    networkProxy: string;
 | 
			
		||||
    hintHandler: string;
 | 
			
		||||
    weth: string;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -106,6 +106,8 @@ export interface ExtendedQuoteReport {
 | 
			
		||||
    decodedUniqueId?: string;
 | 
			
		||||
    sourcesConsidered: ExtendedQuoteReportIndexedEntryOutbound[];
 | 
			
		||||
    sourcesDelivered: ExtendedQuoteReportIndexedEntryOutbound[] | undefined;
 | 
			
		||||
    blockNumber: number | undefined;
 | 
			
		||||
    estimatedGas: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PriceComparisonsReport {
 | 
			
		||||
@@ -205,7 +207,7 @@ export function generateExtendedQuoteReportSources(
 | 
			
		||||
        ..._.flatten(
 | 
			
		||||
            quotes.dexQuotes.map(dex =>
 | 
			
		||||
                dex
 | 
			
		||||
                    .filter(quote => isDexSampleForTotalAmount(quote, marketOperation, amount))
 | 
			
		||||
                    .filter(quote => isDexSampleFilter(quote, amount))
 | 
			
		||||
                    .map(quote => dexSampleToReportSource(quote, marketOperation)),
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
@@ -304,16 +306,9 @@ export function dexSampleToReportSource(ds: DexSample, marketOperation: MarketOp
 | 
			
		||||
 * Checks if a DEX sample is the one that represents the whole amount requested by taker
 | 
			
		||||
 * NOTE: this is used for the QuoteReport to filter samples
 | 
			
		||||
 */
 | 
			
		||||
function isDexSampleForTotalAmount(ds: DexSample, marketOperation: MarketOperation, amount: BigNumber): boolean {
 | 
			
		||||
    // input and output map to different values
 | 
			
		||||
    // based on the market operation
 | 
			
		||||
    if (marketOperation === MarketOperation.Buy) {
 | 
			
		||||
        return ds.input === amount;
 | 
			
		||||
    } else if (marketOperation === MarketOperation.Sell) {
 | 
			
		||||
        return ds.output === amount;
 | 
			
		||||
    } else {
 | 
			
		||||
        throw new Error(`Unexpected marketOperation ${marketOperation}`);
 | 
			
		||||
    }
 | 
			
		||||
function isDexSampleFilter(ds: DexSample, amount: BigNumber): boolean {
 | 
			
		||||
    // The entry is for the total amont, not a sampler entry && there was liquidity in the source
 | 
			
		||||
    return ds.input.eq(amount) && ds.output.isGreaterThan(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								packages/asset-swapper/src/utils/rfq_client_mappers.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								packages/asset-swapper/src/utils/rfq_client_mappers.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
import { FillQuoteTransformerOrderType } from '@0x/protocol-utils';
 | 
			
		||||
 | 
			
		||||
import { SignedNativeOrder } from '../types';
 | 
			
		||||
 | 
			
		||||
import { RfqClientV1Quote } from './irfq_client';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts a RfqClientRfqOrderFirmQuote to a SignedNativeOrder
 | 
			
		||||
 */
 | 
			
		||||
export const toSignedNativeOrder = (quote: RfqClientV1Quote): SignedNativeOrder => {
 | 
			
		||||
    return {
 | 
			
		||||
        type: FillQuoteTransformerOrderType.Rfq,
 | 
			
		||||
        order: quote.order,
 | 
			
		||||
        signature: quote.signature,
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
@@ -8,66 +8,74 @@ import { ContractArtifact } from 'ethereum-types';
 | 
			
		||||
import * as ApproximateBuys from '../test/generated-artifacts/ApproximateBuys.json';
 | 
			
		||||
import * as BalanceChecker from '../test/generated-artifacts/BalanceChecker.json';
 | 
			
		||||
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.json';
 | 
			
		||||
import * as BalancerV2BatchSampler from '../test/generated-artifacts/BalancerV2BatchSampler.json';
 | 
			
		||||
import * as BalancerV2Common from '../test/generated-artifacts/BalancerV2Common.json';
 | 
			
		||||
import * as BalancerV2Sampler from '../test/generated-artifacts/BalancerV2Sampler.json';
 | 
			
		||||
import * as BancorSampler from '../test/generated-artifacts/BancorSampler.json';
 | 
			
		||||
import * as BancorV3Sampler from '../test/generated-artifacts/BancorV3Sampler.json';
 | 
			
		||||
import * as CompoundSampler from '../test/generated-artifacts/CompoundSampler.json';
 | 
			
		||||
import * as CurveSampler from '../test/generated-artifacts/CurveSampler.json';
 | 
			
		||||
import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
 | 
			
		||||
import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json';
 | 
			
		||||
import * as DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json';
 | 
			
		||||
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
 | 
			
		||||
import * as FakeTaker from '../test/generated-artifacts/FakeTaker.json';
 | 
			
		||||
import * as GMXSampler from '../test/generated-artifacts/GMXSampler.json';
 | 
			
		||||
import * as IBalancer from '../test/generated-artifacts/IBalancer.json';
 | 
			
		||||
import * as IBalancerV2Vault from '../test/generated-artifacts/IBalancerV2Vault.json';
 | 
			
		||||
import * as IBancor from '../test/generated-artifacts/IBancor.json';
 | 
			
		||||
import * as IBancorV3 from '../test/generated-artifacts/IBancorV3.json';
 | 
			
		||||
import * as ICurve from '../test/generated-artifacts/ICurve.json';
 | 
			
		||||
import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json';
 | 
			
		||||
import * as IGMX from '../test/generated-artifacts/IGMX.json';
 | 
			
		||||
import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json';
 | 
			
		||||
import * as IMStable from '../test/generated-artifacts/IMStable.json';
 | 
			
		||||
import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json';
 | 
			
		||||
import * as IPlatypus from '../test/generated-artifacts/IPlatypus.json';
 | 
			
		||||
import * as IShell from '../test/generated-artifacts/IShell.json';
 | 
			
		||||
import * as ISmoothy from '../test/generated-artifacts/ISmoothy.json';
 | 
			
		||||
import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json';
 | 
			
		||||
import * as IUniswapV2Router01 from '../test/generated-artifacts/IUniswapV2Router01.json';
 | 
			
		||||
import * as KyberDmmSampler from '../test/generated-artifacts/KyberDmmSampler.json';
 | 
			
		||||
import * as KyberSampler from '../test/generated-artifacts/KyberSampler.json';
 | 
			
		||||
import * as LidoSampler from '../test/generated-artifacts/LidoSampler.json';
 | 
			
		||||
import * as LiquidityProviderSampler from '../test/generated-artifacts/LiquidityProviderSampler.json';
 | 
			
		||||
import * as MakerPSMSampler from '../test/generated-artifacts/MakerPSMSampler.json';
 | 
			
		||||
import * as MooniswapSampler from '../test/generated-artifacts/MooniswapSampler.json';
 | 
			
		||||
import * as MStableSampler from '../test/generated-artifacts/MStableSampler.json';
 | 
			
		||||
import * as MultiBridgeSampler from '../test/generated-artifacts/MultiBridgeSampler.json';
 | 
			
		||||
import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json';
 | 
			
		||||
import * as PlatypusSampler from '../test/generated-artifacts/PlatypusSampler.json';
 | 
			
		||||
import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json';
 | 
			
		||||
import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json';
 | 
			
		||||
import * as SmoothySampler from '../test/generated-artifacts/SmoothySampler.json';
 | 
			
		||||
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
 | 
			
		||||
import * as TestNativeOrderSampler from '../test/generated-artifacts/TestNativeOrderSampler.json';
 | 
			
		||||
import * as TwoHopSampler from '../test/generated-artifacts/TwoHopSampler.json';
 | 
			
		||||
import * as UniswapSampler from '../test/generated-artifacts/UniswapSampler.json';
 | 
			
		||||
import * as UniswapV2Sampler from '../test/generated-artifacts/UniswapV2Sampler.json';
 | 
			
		||||
import * as UniswapV3Sampler from '../test/generated-artifacts/UniswapV3Sampler.json';
 | 
			
		||||
import * as UtilitySampler from '../test/generated-artifacts/UtilitySampler.json';
 | 
			
		||||
import * as VelodromeSampler from '../test/generated-artifacts/VelodromeSampler.json';
 | 
			
		||||
export const artifacts = {
 | 
			
		||||
    ApproximateBuys: ApproximateBuys as ContractArtifact,
 | 
			
		||||
    BalanceChecker: BalanceChecker as ContractArtifact,
 | 
			
		||||
    BalancerSampler: BalancerSampler as ContractArtifact,
 | 
			
		||||
    BalancerV2BatchSampler: BalancerV2BatchSampler as ContractArtifact,
 | 
			
		||||
    BalancerV2Common: BalancerV2Common as ContractArtifact,
 | 
			
		||||
    BalancerV2Sampler: BalancerV2Sampler as ContractArtifact,
 | 
			
		||||
    BancorSampler: BancorSampler as ContractArtifact,
 | 
			
		||||
    BancorV3Sampler: BancorV3Sampler as ContractArtifact,
 | 
			
		||||
    CompoundSampler: CompoundSampler as ContractArtifact,
 | 
			
		||||
    CurveSampler: CurveSampler as ContractArtifact,
 | 
			
		||||
    DODOSampler: DODOSampler as ContractArtifact,
 | 
			
		||||
    DODOV2Sampler: DODOV2Sampler as ContractArtifact,
 | 
			
		||||
    ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
 | 
			
		||||
    FakeTaker: FakeTaker as ContractArtifact,
 | 
			
		||||
    GMXSampler: GMXSampler as ContractArtifact,
 | 
			
		||||
    KyberDmmSampler: KyberDmmSampler as ContractArtifact,
 | 
			
		||||
    KyberSampler: KyberSampler as ContractArtifact,
 | 
			
		||||
    LidoSampler: LidoSampler as ContractArtifact,
 | 
			
		||||
    LiquidityProviderSampler: LiquidityProviderSampler as ContractArtifact,
 | 
			
		||||
    MStableSampler: MStableSampler as ContractArtifact,
 | 
			
		||||
    MakerPSMSampler: MakerPSMSampler as ContractArtifact,
 | 
			
		||||
    MooniswapSampler: MooniswapSampler as ContractArtifact,
 | 
			
		||||
    MultiBridgeSampler: MultiBridgeSampler as ContractArtifact,
 | 
			
		||||
    NativeOrderSampler: NativeOrderSampler as ContractArtifact,
 | 
			
		||||
    PlatypusSampler: PlatypusSampler as ContractArtifact,
 | 
			
		||||
    SamplerUtils: SamplerUtils as ContractArtifact,
 | 
			
		||||
    ShellSampler: ShellSampler as ContractArtifact,
 | 
			
		||||
    SmoothySampler: SmoothySampler as ContractArtifact,
 | 
			
		||||
@@ -76,18 +84,20 @@ export const artifacts = {
 | 
			
		||||
    UniswapV2Sampler: UniswapV2Sampler as ContractArtifact,
 | 
			
		||||
    UniswapV3Sampler: UniswapV3Sampler as ContractArtifact,
 | 
			
		||||
    UtilitySampler: UtilitySampler as ContractArtifact,
 | 
			
		||||
    VelodromeSampler: VelodromeSampler as ContractArtifact,
 | 
			
		||||
    IBalancer: IBalancer as ContractArtifact,
 | 
			
		||||
    IBalancerV2Vault: IBalancerV2Vault as ContractArtifact,
 | 
			
		||||
    IBancor: IBancor as ContractArtifact,
 | 
			
		||||
    IBancorV3: IBancorV3 as ContractArtifact,
 | 
			
		||||
    ICurve: ICurve as ContractArtifact,
 | 
			
		||||
    IKyberNetwork: IKyberNetwork as ContractArtifact,
 | 
			
		||||
    IGMX: IGMX as ContractArtifact,
 | 
			
		||||
    IMStable: IMStable as ContractArtifact,
 | 
			
		||||
    IMooniswap: IMooniswap as ContractArtifact,
 | 
			
		||||
    IMultiBridge: IMultiBridge as ContractArtifact,
 | 
			
		||||
    IPlatypus: IPlatypus as ContractArtifact,
 | 
			
		||||
    IShell: IShell as ContractArtifact,
 | 
			
		||||
    ISmoothy: ISmoothy as ContractArtifact,
 | 
			
		||||
    IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
 | 
			
		||||
    IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact,
 | 
			
		||||
    DummyLiquidityProvider: DummyLiquidityProvider as ContractArtifact,
 | 
			
		||||
    TestERC20BridgeSampler: TestERC20BridgeSampler as ContractArtifact,
 | 
			
		||||
    TestNativeOrderSampler: TestNativeOrderSampler as ContractArtifact,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,8 @@ const GAS_PRICE = new BigNumber(50e9); // 50 gwei
 | 
			
		||||
const NATIVE_ORDER_FEE = new BigNumber(220e3); // 220K gas
 | 
			
		||||
 | 
			
		||||
// DEX samples to fill in MarketSideLiquidity
 | 
			
		||||
const kyberSample1: DexSample = {
 | 
			
		||||
    source: ERC20BridgeSource.Kyber,
 | 
			
		||||
const curveSample: DexSample = {
 | 
			
		||||
    source: ERC20BridgeSource.Curve,
 | 
			
		||||
    input: new BigNumber(10000),
 | 
			
		||||
    output: new BigNumber(10001),
 | 
			
		||||
    fillData: {},
 | 
			
		||||
@@ -33,7 +33,7 @@ const uniswapSample1: DexSample = {
 | 
			
		||||
    output: new BigNumber(10004),
 | 
			
		||||
    fillData: {},
 | 
			
		||||
};
 | 
			
		||||
const dexQuotes: DexSample[] = [kyberSample1, uniswapSample1];
 | 
			
		||||
const dexQuotes: DexSample[] = [curveSample, uniswapSample1];
 | 
			
		||||
 | 
			
		||||
const feeSchedule = {
 | 
			
		||||
    [ERC20BridgeSource.Native]: _.constant(GAS_PRICE.times(NATIVE_ORDER_FEE)),
 | 
			
		||||
@@ -66,6 +66,7 @@ const buyMarketSideLiquidity: MarketSideLiquidity = {
 | 
			
		||||
    },
 | 
			
		||||
    quoteSourceFilters: new SourceFilters(),
 | 
			
		||||
    isRfqSupported: false,
 | 
			
		||||
    blockNumber: 1337420,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const sellMarketSideLiquidity: MarketSideLiquidity = {
 | 
			
		||||
@@ -87,6 +88,7 @@ const sellMarketSideLiquidity: MarketSideLiquidity = {
 | 
			
		||||
    },
 | 
			
		||||
    quoteSourceFilters: new SourceFilters(),
 | 
			
		||||
    isRfqSupported: false,
 | 
			
		||||
    blockNumber: 1337420,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
describe('getComparisonPrices', async () => {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										298
									
								
								packages/asset-swapper/test/contracts/bridge_adapter_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								packages/asset-swapper/test/contracts/bridge_adapter_test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,298 @@
 | 
			
		||||
import { ChainId } from '@0x/contract-addresses';
 | 
			
		||||
import { blockchainTests, constants, describe, expect } from '@0x/contracts-test-utils';
 | 
			
		||||
import {
 | 
			
		||||
    artifacts as zeroExArtifacts,
 | 
			
		||||
    AvalancheBridgeAdapterContract,
 | 
			
		||||
    BSCBridgeAdapterContract,
 | 
			
		||||
    CeloBridgeAdapterContract,
 | 
			
		||||
    EthereumBridgeAdapterContract,
 | 
			
		||||
    FantomBridgeAdapterContract,
 | 
			
		||||
    OptimismBridgeAdapterContract,
 | 
			
		||||
    PolygonBridgeAdapterContract,
 | 
			
		||||
} from '@0x/contracts-zero-ex';
 | 
			
		||||
 | 
			
		||||
import { BUY_SOURCE_FILTER_BY_CHAIN_ID, ERC20BridgeSource, SELL_SOURCE_FILTER_BY_CHAIN_ID } from '../../src';
 | 
			
		||||
import { getErc20BridgeSourceToBridgeSource } from '../../src/utils/market_operation_utils/orders';
 | 
			
		||||
 | 
			
		||||
blockchainTests('Bridge adapter source compatibility tests', env => {
 | 
			
		||||
    describe('Avalanche', () => {
 | 
			
		||||
        let adapter: AvalancheBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await AvalancheBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.AvalancheBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Avalanche].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Avalanche].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('BSC', () => {
 | 
			
		||||
        let adapter: BSCBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await BSCBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.BSCBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.BSC].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.BSC].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('Celo', () => {
 | 
			
		||||
        let adapter: CeloBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await CeloBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.CeloBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Celo].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Celo].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('Ethereum', () => {
 | 
			
		||||
        let adapter: EthereumBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await EthereumBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.EthereumBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('Fantom', () => {
 | 
			
		||||
        let adapter: FantomBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await FantomBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.FantomBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Fantom].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Fantom].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('Optimism', () => {
 | 
			
		||||
        let adapter: OptimismBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await OptimismBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.OptimismBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Optimism].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Optimism].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('Polygon', () => {
 | 
			
		||||
        let adapter: PolygonBridgeAdapterContract;
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            adapter = await PolygonBridgeAdapterContract.deployFrom0xArtifactAsync(
 | 
			
		||||
                zeroExArtifacts.PolygonBridgeAdapter,
 | 
			
		||||
                env.provider,
 | 
			
		||||
                env.txDefaults,
 | 
			
		||||
                zeroExArtifacts,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('sell sources', async () => {
 | 
			
		||||
            const sellSources = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Polygon].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                sellSources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        it('buy sources', async () => {
 | 
			
		||||
            const buySources = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Polygon].exclude([
 | 
			
		||||
                ERC20BridgeSource.Native,
 | 
			
		||||
                ERC20BridgeSource.MultiHop,
 | 
			
		||||
            ]).sources;
 | 
			
		||||
            return Promise.all(
 | 
			
		||||
                buySources.map(async source => {
 | 
			
		||||
                    const isSupported = await adapter
 | 
			
		||||
                        .isSupportedSource(getErc20BridgeSourceToBridgeSource(source))
 | 
			
		||||
                        .callAsync();
 | 
			
		||||
                    expect(isSupported, `${source} is not supported`).to.be.true();
 | 
			
		||||
                }),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
import { ChainId } from '@0x/contract-addresses';
 | 
			
		||||
import { blockchainTests, describe, expect, toBaseUnitAmount, Web3ProviderEngine } from '@0x/contracts-test-utils';
 | 
			
		||||
import { RPCSubprovider } from '@0x/subproviders';
 | 
			
		||||
import { BigNumber, NULL_BYTES, providerUtils } from '@0x/utils';
 | 
			
		||||
import { BigNumber, providerUtils } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { KYBER_CONFIG_BY_CHAIN_ID, MAINNET_TOKENS } from '../../src/utils/market_operation_utils/constants';
 | 
			
		||||
import { artifacts } from '../artifacts';
 | 
			
		||||
import { ERC20BridgeSamplerContract } from '../wrappers';
 | 
			
		||||
 | 
			
		||||
@@ -79,60 +77,4 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('Kyber', () => {
 | 
			
		||||
        const WETH = MAINNET_TOKENS.WETH;
 | 
			
		||||
        const DAI = MAINNET_TOKENS.DAI;
 | 
			
		||||
        const USDC = MAINNET_TOKENS.USDC;
 | 
			
		||||
        const RESERVE_OFFSET = new BigNumber(0);
 | 
			
		||||
        const KYBER_OPTS = {
 | 
			
		||||
            ...KYBER_CONFIG_BY_CHAIN_ID[ChainId.Mainnet],
 | 
			
		||||
            reserveOffset: RESERVE_OFFSET,
 | 
			
		||||
            hint: NULL_BYTES,
 | 
			
		||||
        };
 | 
			
		||||
        describe('sampleSellsFromKyberNetwork()', () => {
 | 
			
		||||
            it('samples sells from Kyber DAI->WETH', async () => {
 | 
			
		||||
                const [, samples] = await testContract
 | 
			
		||||
                    .sampleSellsFromKyberNetwork(KYBER_OPTS, DAI, WETH, [toBaseUnitAmount(1)])
 | 
			
		||||
                    .callAsync({ overrides });
 | 
			
		||||
                expect(samples.length).to.be.bignumber.greaterThan(0);
 | 
			
		||||
                expect(samples[0]).to.be.bignumber.greaterThan(0);
 | 
			
		||||
            });
 | 
			
		||||
            it('samples sells from Kyber WETH->DAI', async () => {
 | 
			
		||||
                const [, samples] = await testContract
 | 
			
		||||
                    .sampleSellsFromKyberNetwork(KYBER_OPTS, WETH, DAI, [toBaseUnitAmount(1)])
 | 
			
		||||
                    .callAsync({ overrides });
 | 
			
		||||
                expect(samples.length).to.be.bignumber.greaterThan(0);
 | 
			
		||||
                expect(samples[0]).to.be.bignumber.greaterThan(0);
 | 
			
		||||
            });
 | 
			
		||||
            it('samples sells from Kyber DAI->USDC', async () => {
 | 
			
		||||
                const [, samples] = await testContract
 | 
			
		||||
                    .sampleSellsFromKyberNetwork(KYBER_OPTS, DAI, USDC, [toBaseUnitAmount(1)])
 | 
			
		||||
                    .callAsync({ overrides });
 | 
			
		||||
                expect(samples.length).to.be.bignumber.greaterThan(0);
 | 
			
		||||
                expect(samples[0]).to.be.bignumber.greaterThan(0);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        describe('sampleBuysFromKyber()', () => {
 | 
			
		||||
            it('samples buys from Kyber WETH->DAI', async () => {
 | 
			
		||||
                // From ETH to DAI
 | 
			
		||||
                // I want to buy 1 DAI
 | 
			
		||||
                const [, samples] = await testContract
 | 
			
		||||
                    .sampleBuysFromKyberNetwork(KYBER_OPTS, WETH, DAI, [toBaseUnitAmount(1)])
 | 
			
		||||
                    .callAsync({ overrides });
 | 
			
		||||
                expect(samples.length).to.be.bignumber.greaterThan(0);
 | 
			
		||||
                expect(samples[0]).to.be.bignumber.greaterThan(0);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('samples buys from Kyber DAI->WETH', async () => {
 | 
			
		||||
                // From USDC to DAI
 | 
			
		||||
                // I want to buy 1 WETH
 | 
			
		||||
                const [, samples] = await testContract
 | 
			
		||||
                    .sampleBuysFromKyberNetwork(KYBER_OPTS, DAI, WETH, [toBaseUnitAmount(1)])
 | 
			
		||||
                    .callAsync({ overrides });
 | 
			
		||||
                expect(samples.length).to.be.bignumber.greaterThan(0);
 | 
			
		||||
                expect(samples[0]).to.be.bignumber.greaterThan(0);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -21,7 +21,7 @@ import { generatePseudoRandomSalt } from './utils/utils';
 | 
			
		||||
const CHAIN_ID = 1;
 | 
			
		||||
const EMPTY_BYTES32 = '0x0000000000000000000000000000000000000000000000000000000000000000';
 | 
			
		||||
// tslint:disable: custom-no-magic-numbers
 | 
			
		||||
describe.skip('DexSampler tests', () => {
 | 
			
		||||
describe('DexSampler tests', () => {
 | 
			
		||||
    const MAKER_TOKEN = randomAddress();
 | 
			
		||||
    const TAKER_TOKEN = randomAddress();
 | 
			
		||||
    const chainId = ChainId.Mainnet;
 | 
			
		||||
@@ -142,40 +142,6 @@ describe.skip('DexSampler tests', () => {
 | 
			
		||||
            expect(fillableAmounts).to.deep.eq(expectedFillableAmounts);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('getKyberSellQuotes()', async () => {
 | 
			
		||||
            const expectedTakerToken = randomAddress();
 | 
			
		||||
            const expectedMakerToken = randomAddress();
 | 
			
		||||
            const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
 | 
			
		||||
            const expectedMakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
 | 
			
		||||
            const sampler = new MockSamplerContract({
 | 
			
		||||
                sampleSellsFromKyberNetwork: (_reserveOffset, takerToken, makerToken, fillAmounts) => {
 | 
			
		||||
                    expect(takerToken).to.eq(expectedTakerToken);
 | 
			
		||||
                    expect(makerToken).to.eq(expectedMakerToken);
 | 
			
		||||
                    expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
 | 
			
		||||
                    return ['0x', '0x', expectedMakerFillAmounts];
 | 
			
		||||
                },
 | 
			
		||||
            });
 | 
			
		||||
            const dexOrderSampler = new DexOrderSampler(
 | 
			
		||||
                chainId,
 | 
			
		||||
                sampler,
 | 
			
		||||
                undefined,
 | 
			
		||||
                undefined,
 | 
			
		||||
                undefined,
 | 
			
		||||
                undefined,
 | 
			
		||||
                async () => undefined,
 | 
			
		||||
            );
 | 
			
		||||
            const [fillableAmounts] = await dexOrderSampler.executeAsync(
 | 
			
		||||
                dexOrderSampler.getKyberSellQuotes(
 | 
			
		||||
                    { hintHandler: randomAddress(), networkProxy: randomAddress(), weth: randomAddress() },
 | 
			
		||||
                    new BigNumber(0),
 | 
			
		||||
                    expectedMakerToken,
 | 
			
		||||
                    expectedTakerToken,
 | 
			
		||||
                    expectedTakerFillAmounts,
 | 
			
		||||
                ),
 | 
			
		||||
            );
 | 
			
		||||
            expect(fillableAmounts).to.deep.eq(expectedMakerFillAmounts);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('getLiquidityProviderSellQuotes()', async () => {
 | 
			
		||||
            const expectedMakerToken = randomAddress();
 | 
			
		||||
            const expectedTakerToken = randomAddress();
 | 
			
		||||
@@ -370,7 +336,6 @@ describe.skip('DexSampler tests', () => {
 | 
			
		||||
            const expectedMakerToken = randomAddress();
 | 
			
		||||
            const sources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.UniswapV2];
 | 
			
		||||
            const ratesBySource: RatesBySource = {
 | 
			
		||||
                [ERC20BridgeSource.Kyber]: getRandomFloat(0, 100),
 | 
			
		||||
                [ERC20BridgeSource.Uniswap]: getRandomFloat(0, 100),
 | 
			
		||||
                [ERC20BridgeSource.UniswapV2]: getRandomFloat(0, 100),
 | 
			
		||||
            };
 | 
			
		||||
 
 | 
			
		||||
@@ -141,6 +141,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
 | 
			
		||||
            ...(side === MarketOperation.Buy
 | 
			
		||||
                ? { type: MarketOperation.Buy, makerTokenFillAmount }
 | 
			
		||||
                : { type: MarketOperation.Sell, takerTokenFillAmount }),
 | 
			
		||||
            blockNumber: 1337420,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ import {
 | 
			
		||||
import { FillQuoteTransformerOrderType, LimitOrder, RfqOrder, SignatureType } from '@0x/protocol-utils';
 | 
			
		||||
import { BigNumber, hexUtils, NULL_BYTES } from '@0x/utils';
 | 
			
		||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
			
		||||
import { Pool } from '@balancer-labs/sor/dist/types';
 | 
			
		||||
import { Pool } from 'balancer-labs-sor-v1/dist/types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as TypeMoq from 'typemoq';
 | 
			
		||||
 | 
			
		||||
@@ -49,10 +49,10 @@ const MAKER_TOKEN = randomAddress();
 | 
			
		||||
const TAKER_TOKEN = randomAddress();
 | 
			
		||||
 | 
			
		||||
const DEFAULT_INCLUDED = [
 | 
			
		||||
    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
    ERC20BridgeSource.Kyber,
 | 
			
		||||
    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
    ERC20BridgeSource.Native,
 | 
			
		||||
    ERC20BridgeSource.Uniswap,
 | 
			
		||||
    ERC20BridgeSource.Curve,
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const DEFAULT_EXCLUDED = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources.filter(
 | 
			
		||||
@@ -319,9 +319,9 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
    const DEFAULT_RATES: RatesBySource = {
 | 
			
		||||
        ...ZERO_RATES,
 | 
			
		||||
        [ERC20BridgeSource.Native]: createDecreasingRates(NUM_SAMPLES),
 | 
			
		||||
        [ERC20BridgeSource.Eth2Dai]: createDecreasingRates(NUM_SAMPLES),
 | 
			
		||||
        [ERC20BridgeSource.SushiSwap]: createDecreasingRates(NUM_SAMPLES),
 | 
			
		||||
        [ERC20BridgeSource.Uniswap]: createDecreasingRates(NUM_SAMPLES),
 | 
			
		||||
        [ERC20BridgeSource.Kyber]: createDecreasingRates(NUM_SAMPLES),
 | 
			
		||||
        [ERC20BridgeSource.Curve]: createDecreasingRates(NUM_SAMPLES),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    interface FillDataBySource {
 | 
			
		||||
@@ -337,7 +337,6 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            deadline: Math.floor(Date.now() / 1000) + 300,
 | 
			
		||||
        },
 | 
			
		||||
        [ERC20BridgeSource.Bancor]: { path: [], networkAddress: randomAddress() },
 | 
			
		||||
        [ERC20BridgeSource.Kyber]: { hint: '0x', reserveId: '0x', networkAddress: randomAddress() },
 | 
			
		||||
        [ERC20BridgeSource.Curve]: {
 | 
			
		||||
            pool: {
 | 
			
		||||
                poolAddress: randomAddress(),
 | 
			
		||||
@@ -349,28 +348,6 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            fromTokenIdx: 0,
 | 
			
		||||
            toTokenIdx: 1,
 | 
			
		||||
        },
 | 
			
		||||
        [ERC20BridgeSource.Swerve]: {
 | 
			
		||||
            pool: {
 | 
			
		||||
                poolAddress: randomAddress(),
 | 
			
		||||
                tokens: [TAKER_TOKEN, MAKER_TOKEN],
 | 
			
		||||
                exchangeFunctionSelector: hexUtils.random(4),
 | 
			
		||||
                sellQuoteFunctionSelector: hexUtils.random(4),
 | 
			
		||||
                buyQuoteFunctionSelector: hexUtils.random(4),
 | 
			
		||||
            },
 | 
			
		||||
            fromTokenIdx: 0,
 | 
			
		||||
            toTokenIdx: 1,
 | 
			
		||||
        },
 | 
			
		||||
        [ERC20BridgeSource.SnowSwap]: {
 | 
			
		||||
            pool: {
 | 
			
		||||
                poolAddress: randomAddress(),
 | 
			
		||||
                tokens: [TAKER_TOKEN, MAKER_TOKEN],
 | 
			
		||||
                exchangeFunctionSelector: hexUtils.random(4),
 | 
			
		||||
                sellQuoteFunctionSelector: hexUtils.random(4),
 | 
			
		||||
                buyQuoteFunctionSelector: hexUtils.random(4),
 | 
			
		||||
            },
 | 
			
		||||
            fromTokenIdx: 0,
 | 
			
		||||
            toTokenIdx: 1,
 | 
			
		||||
        },
 | 
			
		||||
        [ERC20BridgeSource.Smoothy]: {
 | 
			
		||||
            pool: {
 | 
			
		||||
                poolAddress: randomAddress(),
 | 
			
		||||
@@ -404,9 +381,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
        [ERC20BridgeSource.Dodo]: {},
 | 
			
		||||
        [ERC20BridgeSource.DodoV2]: {},
 | 
			
		||||
        [ERC20BridgeSource.CryptoCom]: { tokenAddressPath: [] },
 | 
			
		||||
        [ERC20BridgeSource.Linkswap]: { tokenAddressPath: [] },
 | 
			
		||||
        [ERC20BridgeSource.Uniswap]: { router: randomAddress() },
 | 
			
		||||
        [ERC20BridgeSource.Eth2Dai]: { router: randomAddress() },
 | 
			
		||||
        [ERC20BridgeSource.MakerPsm]: {},
 | 
			
		||||
        [ERC20BridgeSource.KyberDmm]: { tokenAddressPath: [], router: randomAddress(), poolsPath: [] },
 | 
			
		||||
    };
 | 
			
		||||
@@ -483,7 +458,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('queries `numSamples` samples', async () => {
 | 
			
		||||
                const numSamples = _.random(1, NUM_SAMPLES);
 | 
			
		||||
                // neon-router requires at least 3 samples
 | 
			
		||||
                const numSamples = _.random(3, NUM_SAMPLES);
 | 
			
		||||
                let actualNumSamples = 0;
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getSellQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
 | 
			
		||||
@@ -501,6 +477,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                await getMarketSellOrdersAsync(marketOperationUtils, ORDERS, FILL_AMOUNT, {
 | 
			
		||||
                    ...DEFAULT_OPTS,
 | 
			
		||||
                    numSamples,
 | 
			
		||||
                    neonRouterNumSamples: numSamples,
 | 
			
		||||
                });
 | 
			
		||||
                expect(actualNumSamples).eq(numSamples);
 | 
			
		||||
            });
 | 
			
		||||
@@ -532,7 +509,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('does not poll DEXes in `excludedSources`', async () => {
 | 
			
		||||
                const excludedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.Eth2Dai];
 | 
			
		||||
                const excludedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.SushiSwap];
 | 
			
		||||
                let sourcesPolled: ERC20BridgeSource[] = [];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getSellQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
 | 
			
		||||
@@ -562,7 +539,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('only polls DEXes in `includedSources`', async () => {
 | 
			
		||||
                const includedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.Eth2Dai];
 | 
			
		||||
                const includedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.SushiSwap];
 | 
			
		||||
                let sourcesPolled: ERC20BridgeSource[] = [];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getSellQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
 | 
			
		||||
@@ -746,6 +723,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                                ],
 | 
			
		||||
                            },
 | 
			
		||||
                            isRfqSupported: true,
 | 
			
		||||
                            blockNumber: 1337420,
 | 
			
		||||
                        };
 | 
			
		||||
                    });
 | 
			
		||||
                const result = await mockedMarketOpUtils.object.getOptimizerResultAsync(
 | 
			
		||||
@@ -1054,8 +1032,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const rates: RatesBySource = { ...DEFAULT_RATES };
 | 
			
		||||
                rates[ERC20BridgeSource.Native] = [0.4, 0.3, 0.2, 0.1];
 | 
			
		||||
                rates[ERC20BridgeSource.Uniswap] = [0.5, 0.05, 0.05, 0.05];
 | 
			
		||||
                rates[ERC20BridgeSource.Eth2Dai] = [0.6, 0.05, 0.05, 0.05];
 | 
			
		||||
                rates[ERC20BridgeSource.Kyber] = [0, 0, 0, 0]; // unused
 | 
			
		||||
                rates[ERC20BridgeSource.SushiSwap] = [0.6, 0.05, 0.05, 0.05];
 | 
			
		||||
                rates[ERC20BridgeSource.Curve] = [0, 0, 0, 0]; // unused
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getSellQuotes: createGetMultipleSellQuotesOperationFromRates(rates),
 | 
			
		||||
                });
 | 
			
		||||
@@ -1068,7 +1046,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const improvedOrders = improvedOrdersResponse.optimizedOrders;
 | 
			
		||||
                const orderSources = improvedOrders.map(o => o.fills[0].source);
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
@@ -1078,15 +1056,15 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
 | 
			
		||||
            const ETH_TO_MAKER_RATE = 1.5;
 | 
			
		||||
 | 
			
		||||
            it('factors in fees for native orders', async () => {
 | 
			
		||||
            // TODO: disabled as this is not supported by neon-router
 | 
			
		||||
            it.skip('factors in fees for native orders', async () => {
 | 
			
		||||
                // Native orders will have the best rates but have fees,
 | 
			
		||||
                // dropping their effective rates.
 | 
			
		||||
                const nativeFeeRate = 0.06;
 | 
			
		||||
                const rates: RatesBySource = {
 | 
			
		||||
                    [ERC20BridgeSource.Native]: [1, 0.99, 0.98, 0.97], // Effectively [0.94, 0.93, 0.92, 0.91]
 | 
			
		||||
                    [ERC20BridgeSource.Uniswap]: [0.96, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Eth2Dai]: [0.95, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Kyber]: [0.1, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.SushiSwap]: [0.95, 0.1, 0.1, 0.1],
 | 
			
		||||
                };
 | 
			
		||||
                const feeSchedule = {
 | 
			
		||||
                    [ERC20BridgeSource.Native]: _.constant(
 | 
			
		||||
@@ -1110,20 +1088,18 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                ];
 | 
			
		||||
                expect(orderSources.sort()).to.deep.eq(expectedSources.sort());
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('factors in fees for dexes', async () => {
 | 
			
		||||
                // Kyber will have the best rates but will have fees,
 | 
			
		||||
                // dropping its effective rates.
 | 
			
		||||
                const uniswapFeeRate = 0.2;
 | 
			
		||||
                const rates: RatesBySource = {
 | 
			
		||||
                    [ERC20BridgeSource.Native]: [0.95, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Kyber]: [0.1, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Eth2Dai]: [0.92, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Curve]: [0.1, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.SushiSwap]: [0.92, 0.1, 0.1, 0.1],
 | 
			
		||||
                    // Effectively [0.8, ~0.5, ~0, ~0]
 | 
			
		||||
                    [ERC20BridgeSource.Uniswap]: [1, 0.7, 0.2, 0.2],
 | 
			
		||||
                };
 | 
			
		||||
@@ -1148,7 +1124,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const orderSources = improvedOrders.map(o => o.fills[0].source);
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                ];
 | 
			
		||||
                expect(orderSources.sort()).to.deep.eq(expectedSources.sort());
 | 
			
		||||
@@ -1156,8 +1132,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
 | 
			
		||||
            it('can mix one concave source', async () => {
 | 
			
		||||
                const rates: RatesBySource = {
 | 
			
		||||
                    [ERC20BridgeSource.Kyber]: [0, 0, 0, 0], // Won't use
 | 
			
		||||
                    [ERC20BridgeSource.Eth2Dai]: [0.5, 0.85, 0.75, 0.75], // Concave
 | 
			
		||||
                    [ERC20BridgeSource.Curve]: [0, 0, 0, 0], // Won't use
 | 
			
		||||
                    [ERC20BridgeSource.SushiSwap]: [0.5, 0.85, 0.75, 0.75], // Concave
 | 
			
		||||
                    [ERC20BridgeSource.Uniswap]: [0.96, 0.2, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Native]: [0.95, 0.2, 0.2, 0.1],
 | 
			
		||||
                };
 | 
			
		||||
@@ -1174,19 +1150,21 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const improvedOrders = improvedOrdersResponse.optimizedOrders;
 | 
			
		||||
                const orderSources = improvedOrders.map(o => o.fills[0].source);
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                ];
 | 
			
		||||
                expect(orderSources.sort()).to.deep.eq(expectedSources.sort());
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('does not create a fallback if below maxFallbackSlippage', async () => {
 | 
			
		||||
            // NOTE: Currently fallbacks for native orders are disabled
 | 
			
		||||
            // TODO: remove this if we remove fallbacks completely
 | 
			
		||||
            it.skip('does not create a fallback if below maxFallbackSlippage', async () => {
 | 
			
		||||
                const rates: RatesBySource = {};
 | 
			
		||||
                rates[ERC20BridgeSource.Native] = [1, 1, 0.01, 0.01];
 | 
			
		||||
                rates[ERC20BridgeSource.Uniswap] = [1, 1, 0.01, 0.01];
 | 
			
		||||
                rates[ERC20BridgeSource.Eth2Dai] = [0.49, 0.49, 0.49, 0.49];
 | 
			
		||||
                rates[ERC20BridgeSource.Kyber] = [0.35, 0.2, 0.01, 0.01];
 | 
			
		||||
                rates[ERC20BridgeSource.SushiSwap] = [0.49, 0.49, 0.49, 0.49];
 | 
			
		||||
                rates[ERC20BridgeSource.Curve] = [0.35, 0.2, 0.01, 0.01];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getSellQuotes: createGetMultipleSellQuotesOperationFromRates(rates),
 | 
			
		||||
                });
 | 
			
		||||
@@ -1325,7 +1303,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('queries `numSamples` samples', async () => {
 | 
			
		||||
                const numSamples = _.random(1, 16);
 | 
			
		||||
                // neon-router requires at least 3 samples
 | 
			
		||||
                const numSamples = _.random(3, 16);
 | 
			
		||||
                let actualNumSamples = 0;
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getBuyQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
 | 
			
		||||
@@ -1343,6 +1322,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                await getMarketBuyOrdersAsync(marketOperationUtils, ORDERS, FILL_AMOUNT, {
 | 
			
		||||
                    ...DEFAULT_OPTS,
 | 
			
		||||
                    numSamples,
 | 
			
		||||
                    // Make sure to use same number of samples in neon-router for compatibility
 | 
			
		||||
                    neonRouterNumSamples: numSamples,
 | 
			
		||||
                });
 | 
			
		||||
                expect(actualNumSamples).eq(numSamples);
 | 
			
		||||
            });
 | 
			
		||||
@@ -1377,7 +1358,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('does not poll DEXes in `excludedSources`', async () => {
 | 
			
		||||
                const excludedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.Eth2Dai];
 | 
			
		||||
                const excludedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.SushiSwap];
 | 
			
		||||
                let sourcesPolled: ERC20BridgeSource[] = [];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getBuyQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
 | 
			
		||||
@@ -1407,7 +1388,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('only polls DEXes in `includedSources`', async () => {
 | 
			
		||||
                const includedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.Eth2Dai];
 | 
			
		||||
                const includedSources = [ERC20BridgeSource.Uniswap, ERC20BridgeSource.SushiSwap];
 | 
			
		||||
                let sourcesPolled: ERC20BridgeSource[] = [];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getBuyQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
 | 
			
		||||
@@ -1494,11 +1475,12 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('can mix convex sources', async () => {
 | 
			
		||||
            // TODO: disabled as this is not supported by neon-router
 | 
			
		||||
            it.skip('can mix convex sources', async () => {
 | 
			
		||||
                const rates: RatesBySource = { ...ZERO_RATES };
 | 
			
		||||
                rates[ERC20BridgeSource.Native] = [0.4, 0.3, 0.2, 0.1];
 | 
			
		||||
                rates[ERC20BridgeSource.Uniswap] = [0.5, 0.05, 0.05, 0.05];
 | 
			
		||||
                rates[ERC20BridgeSource.Eth2Dai] = [0.6, 0.05, 0.05, 0.05];
 | 
			
		||||
                rates[ERC20BridgeSource.SushiSwap] = [0.6, 0.05, 0.05, 0.05];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getBuyQuotes: createGetMultipleBuyQuotesOperationFromRates(rates),
 | 
			
		||||
                });
 | 
			
		||||
@@ -1511,7 +1493,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const improvedOrders = improvedOrdersResponse.optimizedOrders;
 | 
			
		||||
                const orderSources = improvedOrders.map(o => o.fills[0].source);
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
@@ -1521,7 +1503,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
 | 
			
		||||
            const ETH_TO_TAKER_RATE = 1.5;
 | 
			
		||||
 | 
			
		||||
            it('factors in fees for native orders', async () => {
 | 
			
		||||
            // TODO: disabled as this is not supported by neon-router
 | 
			
		||||
            it.skip('factors in fees for native orders', async () => {
 | 
			
		||||
                // Native orders will have the best rates but have fees,
 | 
			
		||||
                // dropping their effective rates.
 | 
			
		||||
                const nativeFeeRate = 0.06;
 | 
			
		||||
@@ -1529,8 +1512,8 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                    ...ZERO_RATES,
 | 
			
		||||
                    [ERC20BridgeSource.Native]: [1, 0.99, 0.98, 0.97], // Effectively [0.94, ~0.93, ~0.92, ~0.91]
 | 
			
		||||
                    [ERC20BridgeSource.Uniswap]: [0.96, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Eth2Dai]: [0.95, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Kyber]: [0.1, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.SushiSwap]: [0.95, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.Curve]: [0.1, 0.1, 0.1, 0.1],
 | 
			
		||||
                };
 | 
			
		||||
                const feeSchedule = {
 | 
			
		||||
                    [ERC20BridgeSource.Native]: _.constant(
 | 
			
		||||
@@ -1553,7 +1536,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const orderSources = improvedOrders.map(o => o.fills[0].source);
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                ];
 | 
			
		||||
@@ -1569,7 +1552,7 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                    [ERC20BridgeSource.Native]: [0.95, 0.1, 0.1, 0.1],
 | 
			
		||||
                    // Effectively [0.8, ~0.5, ~0, ~0]
 | 
			
		||||
                    [ERC20BridgeSource.Uniswap]: [1, 0.7, 0.2, 0.2],
 | 
			
		||||
                    [ERC20BridgeSource.Eth2Dai]: [0.92, 0.1, 0.1, 0.1],
 | 
			
		||||
                    [ERC20BridgeSource.SushiSwap]: [0.92, 0.1, 0.1, 0.1],
 | 
			
		||||
                };
 | 
			
		||||
                const feeSchedule = {
 | 
			
		||||
                    [ERC20BridgeSource.Uniswap]: _.constant(
 | 
			
		||||
@@ -1592,17 +1575,19 @@ describe('MarketOperationUtils tests', () => {
 | 
			
		||||
                const orderSources = improvedOrders.map(o => o.fills[0].source);
 | 
			
		||||
                const expectedSources = [
 | 
			
		||||
                    ERC20BridgeSource.Native,
 | 
			
		||||
                    ERC20BridgeSource.Eth2Dai,
 | 
			
		||||
                    ERC20BridgeSource.SushiSwap,
 | 
			
		||||
                    ERC20BridgeSource.Uniswap,
 | 
			
		||||
                ];
 | 
			
		||||
                expect(orderSources.sort()).to.deep.eq(expectedSources.sort());
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('does not create a fallback if below maxFallbackSlippage', async () => {
 | 
			
		||||
            // NOTE: Currently fallbacks for native orders are disabled
 | 
			
		||||
            // TODO: remove this if we remove fallbacks completely
 | 
			
		||||
            it.skip('does not create a fallback if below maxFallbackSlippage', async () => {
 | 
			
		||||
                const rates: RatesBySource = { ...ZERO_RATES };
 | 
			
		||||
                rates[ERC20BridgeSource.Native] = [1, 1, 0.01, 0.01];
 | 
			
		||||
                rates[ERC20BridgeSource.Uniswap] = [1, 1, 0.01, 0.01];
 | 
			
		||||
                rates[ERC20BridgeSource.Eth2Dai] = [0.49, 0.49, 0.49, 0.49];
 | 
			
		||||
                rates[ERC20BridgeSource.SushiSwap] = [0.49, 0.49, 0.49, 0.49];
 | 
			
		||||
                replaceSamplerOps({
 | 
			
		||||
                    getBuyQuotes: createGetMultipleBuyQuotesOperationFromRates(rates),
 | 
			
		||||
                });
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user