Compare commits

..

6 Commits

Author SHA1 Message Date
Noah Khamliche
4a18c1b0f8 fix rfq/otc encoding logic 2022-07-14 18:09:28 -04:00
Noah Khamliche
3c30c92acf changelog version bumps 2022-07-14 17:41:38 -04:00
Noah Khamliche
cc1cc69ba5 trying to fix tests 2022-07-14 17:20:11 -04:00
Noah Khamliche
4f57736c82 added fill logic for otcOrders in AS, as well as MultiplexBatchFill for otc 2022-07-14 15:43:07 -04:00
Noah Khamliche
f466f8310f added otc orders to quote report generator 2022-07-13 22:01:59 -04:00
Noah Khamliche
8f5e7d7fb5 add new fqt and support for otc orders in asset-swapper exchange proxy swap qutoe consumer 2022-07-13 21:56:50 -04:00
115 changed files with 3170 additions and 10435 deletions

View File

@@ -1,27 +1,16 @@
version: 2.1
parameters:
cache_version:
type: string
default: v4
jobs:
build:
resource_class: xlarge
docker:
- image: node:16
environment:
NODE_OPTIONS: "--max-old-space-size=16384"
NODE_OPTIONS: '--max-old-space-size=16384'
working_directory: ~/repo
steps:
- checkout
- run: git submodule update --init --recursive
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- run:
name: install-yarn
command: npm install --force --global yarn@1.22.0
@@ -29,176 +18,77 @@ jobs:
name: yarn
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
- setup_remote_docker
- run: yarn build:ci
- run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci
- save_cache:
key: cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/project/contracts/erc20/node_modules
- ~/project/contracts/test-utils/node_modules
- ~/project/contracts/treasury/node_modules
- ~/project/contracts/utils/node_modules
- ~/project/contracts/zero-ex/node_modules
- ~/project/node_modules
- ~/project/packages/asset-swapper/node_modules
- ~/project/packages/contract-addresses/node_modules
- ~/project/packages/contract-artifacts/node_modules
- ~/project/packages/contract-wrappers/node_modules
- ~/project/packages/protocol-utils/node_modules
- ~/.cache/yarn
- save_cache:
key: lib-{{ .Environment.CIRCLE_BRANCH }}
paths:
- ~/project/contracts/erc20/generated-artifacts/
- ~/project/contracts/erc20/generated-wrappers/
- ~/project/contracts/erc20/lib/
- ~/project/contracts/erc20/test/generated-artifacts/
- ~/project/contracts/erc20/test/generated-wrappers/
- ~/project/contracts/test-utils/lib/
- ~/project/contracts/treasury/generated-artifacts/
- ~/project/contracts/treasury/generated-wrappers/
- ~/project/contracts/treasury/lib/
- ~/project/contracts/treasury/test/generated-artifacts/
- ~/project/contracts/treasury/test/generated-wrappers/
- ~/project/contracts/utils/generated-artifacts/
- ~/project/contracts/utils/generated-wrappers/
- ~/project/contracts/utils/lib/
- ~/project/contracts/utils/test/generated-artifacts/
- ~/project/contracts/utils/test/generated-wrappers/
- ~/project/contracts/zero-ex/generated-artifacts/
- ~/project/contracts/zero-ex/generated-wrappers/
- ~/project/contracts/zero-ex/lib/
- ~/project/contracts/zero-ex/test/generated-artifacts/
- ~/project/contracts/zero-ex/test/generated-wrappers/
- ~/project/packages/contract-addresses/lib/
- ~/project/packages/contract-artifacts/lib/
- ~/project/packages/contract-wrappers/lib/
- ~/project/packages/protocol-utils/lib/
- ~/repo
- store_artifacts:
path: ~/repo/packages/abi-gen/test-cli/output
- store_artifacts:
path: ~/repo/packages/contract-wrappers/generated_docs
test-exchange-ganache:
resource_class: xlarge
resource_class: medium+
docker:
- image: node:16
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun -p @0x/contracts-exchange -m --serial -c test:circleci
test-integrations-ganache:
resource_class: xlarge
resource_class: medium+
docker:
- image: node:16
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun -p @0x/contracts-integrations -m --serial -c test:circleci
test-contracts-staking-ganache:
resource_class: xlarge
resource_class: medium+
docker:
- image: node:16
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun -p @0x/contracts-staking -m --serial -c test:circleci
test-contracts-extra-ganache:
resource_class: xlarge
resource_class: medium+
docker:
- image: node:16
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun -p @0x/contracts-exchange-forwarder -p @0x/contracts-coordinator -m --serial -c test:circleci
test-contracts-rest-ganache:
resource_class: xlarge
resource_class: medium+
docker:
- image: node:16
working_directory: ~/repo
steps:
- checkout
- run: |
git diff --name-only development >> changed.txt
if ! grep -q \.sol changed.txt; then
circleci-agent step halt
fi
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- run: |
yarn wsrun \
-p @0x/contracts-multisig \
-p @0x/contracts-utils \
-p @0x/contracts-exchange-libs \
-p @0x/contracts-erc20 \
-p @0x/contracts-erc721 \
-p @0x/contracts-erc1155 \
-p @0x/contracts-asset-proxy \
-p @0x/contracts-broker \
-p @0x/contracts-zero-ex \
-m --serial -c test:circleci
test-foundry:
resource_class: xlarge
docker:
- image: ghcr.io/foundry-rs/foundry:latest
steps:
- checkout
- run: |
git diff --name-only development >> changed.txt
cat changed.txt
if ! grep -q \.sol changed.txt; then
circleci-agent step halt
fi
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- run: git submodule update --init --recursive
- run:
command: forge test
working_directory: ~/project/contracts/zero-ex
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun -p @0x/contracts-multisig -p @0x/contracts-utils -p @0x/contracts-exchange-libs -p @0x/contracts-erc20 -p @0x/contracts-erc721 -p @0x/contracts-erc1155 -p @0x/contracts-asset-proxy -p @0x/contracts-broker -p @0x/contracts-zero-ex -m --serial -c test:circleci
test-publish:
resource_class: large
environment:
NODE_OPTIONS: "--max-old-space-size=6442"
NODE_OPTIONS: '--max-old-space-size=6442'
docker:
- image: node:16
- image: 0xorg/verdaccio
working_directory: ~/repo
steps:
- checkout
- run: |
git diff --name-only development >> changed.txt
cat changed.txt
if ! grep -q packages/ changed.txt; then
circleci-agent step halt
fi
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: yarn test:publish:circleci
no_output_timeout: 1800
@@ -207,84 +97,71 @@ jobs:
test-doc-generation:
docker:
- image: node:16
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
command: yarn test:generate_docs:circleci
no_output_timeout: 1200
test-rest:
docker:
- image: node:16
working_directory: ~/repo
environment:
RUST_ROUTER: "true"
RUST_ROUTER: 'true'
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun -p @0x/contracts-test-utils -m --serial -c test:circleci
- run: yarn wsrun -p @0x/contract-addresses -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/order-utils -m --serial -c test:circleci
- run: yarn wsrun -p @0x/asset-swapper -m --serial -c test:circleci
- save_cache:
key: coverage-contract-wrappers-test-{{ checksum "yarn.lock" }}
key: coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contract-wrappers-test/coverage/lcov.info
- save_cache:
key: coverage-order-utils-{{ checksum "yarn.lock" }}
key: coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/order-utils/coverage/lcov.info
- save_cache:
key: coverage-web3-wrapper-{{ checksum "yarn.lock" }}
key: coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/web3-wrapper/coverage/lcov.info
static-tests:
resource_class: large
working_directory: ~/repo
docker:
- image: node:16
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- lib-{{ .Environment.CIRCLE_BRANCH }}
- run:
command: yarn lerna run lint
- run:
command: yarn prettier:ci
- run:
command: yarn deps_versions:ci
- run:
command: yarn diff_md_docs:ci
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn lerna run lint
- run: yarn prettier:ci
- run: yarn deps_versions:ci
- run: yarn diff_md_docs:ci
submit-coverage:
docker:
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
keys:
- cache-{{ checksum "yarn.lock" }}-<< pipeline.parameters.cache_version >>
- repo-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- lib-{{ .Environment.CIRCLE_BRANCH }}
- coverage-contract-wrappers-test-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contract-wrappers-test-{{ checksum "yarn.lock" }}
- coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-order-utils-{{ checksum "yarn.lock" }}
- restore_cache:
keys:
- coverage-contracts-{{ checksum "yarn.lock" }}
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn report_coverage
workflows:
version: 2
@@ -304,9 +181,6 @@ workflows:
# - test-contracts-extra-ganache:
# requires:
# - build
- test-foundry:
requires:
- build
- test-contracts-rest-ganache:
requires:
- build

9
.gitignore vendored
View File

@@ -173,15 +173,6 @@ contracts/zero-ex/test/generated-wrappers/
contracts/treasury/generated-wrappers/
contracts/treasury/test/generated-wrappers/
# foundry artifacts
contracts/zero-ex/foundry-artifacts/
# foundry cache
contracts/zero-ex/foundry-cache/
# typechain wrappers
contracts/zero-ex/typechain-wrappers/
# Doc README copy
packages/*/docs/README.md

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "contracts/zero-ex/contracts/deps/forge-std"]
path = contracts/zero-ex/contracts/deps/forge-std
url = https://github.com/foundry-rs/forge-std

View File

@@ -6,15 +6,15 @@
# https://git-scm.com/docs/gitignore#_pattern_format
packages/asset-swapper/ @dekz @dextracker @kyu-c
packages/asset-swapper/ @dekz @mzhu25 @dextracker @kh-chang
# Dev tools & setup
.circleci/ @dekz
packages/contract-addresses/ @dekz @dextracker @kyu-c
packages/contract-artifacts/ @dekz
packages/protocol-utils/ @dekz
.circleci/ @dekz @mzhu25
packages/contract-addresses/ @dekz @mzhu25 @dextracker @kh-chang
packages/contract-artifacts/ @dekz @mzhu25
packages/protocol-utils/ @dekz @mzhu25
# Protocol/smart contracts
contracts/ @dekz @dextracker
contracts/ @dekz @mzhu25 @dextracker

View File

@@ -34,6 +34,7 @@ These packages are all under development. See [/contracts/README.md](/contracts/
| Package | Version | Description |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| [`@0x/asset-swapper`](/packages/asset-swapper) | [![npm](https://img.shields.io/npm/v/@0x/asset-swapper.svg)](https://www.npmjs.com/package/@0x/asset-swapper) | Package used to find and create aggregated swaps |
| [`@0x/protocol-utils`](/packages/protocol-utils) | [![npm](https://img.shields.io/npm/v/@0x/protocol-utils.svg)](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) | [![npm](https://img.shields.io/npm/v/@0x/contract-addresses.svg)](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) | [![npm](https://img.shields.io/npm/v/@0x/contract-wrappers.svg)](https://www.npmjs.com/package/@0x/contract-wrappers) | JS/TS wrappers for interacting with the 0x smart contracts |
@@ -81,7 +82,7 @@ yarn build
To build a specific package:
```bash
PKG=@0x/protocol-utils yarn build
PKG=@0x/asset-swapper yarn build
```
To build all contracts packages:
@@ -104,7 +105,7 @@ To watch a specific package and all it's dependent packages:
PKG=[NPM_PACKAGE_NAME] yarn watch
e.g
PKG=@0x/protocol-utils yarn watch
PKG=@0x/asset-swapper yarn watch
```
### Clean
@@ -118,7 +119,7 @@ yarn clean
Clean a specific package
```bash
PKG=@0x/protocol-utils yarn clean
PKG=@0x/asset-swapper yarn clean
```
### Rebuild
@@ -132,7 +133,7 @@ yarn rebuild
To re-build (clean & build) a specific package & it's deps:
```bash
PKG=@0x/protocol-utils yarn rebuild
PKG=@0x/asset-swapper yarn rebuild
```
### Lint
@@ -146,7 +147,7 @@ yarn lint
Lint a specific package:
```bash
PKG=@0x/protocol-utils yarn lint
PKG=@0x/asset-swapper yarn lint
```
### Run Tests
@@ -160,7 +161,7 @@ yarn test
Run a specific package's test:
```bash
PKG=@0x/protocol-utils yarn test
PKG=@0x/asset-swapper yarn test
```
Run all contracts packages tests:

View File

@@ -1,94 +1,4 @@
[
{
"timestamp": 1662559804,
"version": "3.3.42",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662147076,
"version": "3.3.41",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662046042,
"version": "3.3.40",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661462289,
"version": "3.3.39",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661459661,
"version": "3.3.38",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661145612,
"version": "3.3.37",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660093941,
"version": "3.3.36",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660073235,
"version": "3.3.35",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1659750766,
"version": "3.3.34",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1658950329,
"version": "3.3.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1655244958,
"version": "3.3.32",

View File

@@ -5,46 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.3.42 - _September 7, 2022_
* Dependencies updated
## v3.3.41 - _September 2, 2022_
* Dependencies updated
## v3.3.40 - _September 1, 2022_
* Dependencies updated
## v3.3.39 - _August 25, 2022_
* Dependencies updated
## v3.3.38 - _August 25, 2022_
* Dependencies updated
## v3.3.37 - _August 22, 2022_
* Dependencies updated
## v3.3.36 - _August 10, 2022_
* Dependencies updated
## v3.3.35 - _August 9, 2022_
* Dependencies updated
## v3.3.34 - _August 6, 2022_
* Dependencies updated
## v3.3.33 - _July 27, 2022_
* Dependencies updated
## v3.3.32 - _June 14, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc20",
"version": "3.3.42",
"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.8.1",
"@0x/contracts-gen": "^2.0.47",
"@0x/contracts-test-utils": "^5.4.33",
"@0x/contracts-utils": "^4.8.23",
"@0x/dev-utils": "^5.0.0",
"@0x/sol-compiler": "^4.8.2",
"@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.6",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^7.0.0",
"@0x/web3-wrapper": "^8.0.0",
"@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.7.1",
"ethereum-types": "^3.7.0",
"lodash": "^4.17.11",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
@@ -82,7 +82,7 @@
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^7.0.0",
"@0x/base-contract": "^6.5.0",
"ethers": "~4.0.4"
},
"publishConfig": {

View File

@@ -1,94 +1,4 @@
[
{
"timestamp": 1662559804,
"version": "5.4.33",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662147076,
"version": "5.4.32",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662046042,
"version": "5.4.31",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661462289,
"version": "5.4.30",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661459661,
"version": "5.4.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661145612,
"version": "5.4.28",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660093941,
"version": "5.4.27",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660073235,
"version": "5.4.26",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1659750766,
"version": "5.4.25",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1658950329,
"version": "5.4.24",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1655244958,
"version": "5.4.23",

View File

@@ -5,46 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v5.4.33 - _September 7, 2022_
* Dependencies updated
## v5.4.32 - _September 2, 2022_
* Dependencies updated
## v5.4.31 - _September 1, 2022_
* Dependencies updated
## v5.4.30 - _August 25, 2022_
* Dependencies updated
## v5.4.29 - _August 25, 2022_
* Dependencies updated
## v5.4.28 - _August 22, 2022_
* Dependencies updated
## v5.4.27 - _August 10, 2022_
* Dependencies updated
## v5.4.26 - _August 9, 2022_
* Dependencies updated
## v5.4.25 - _August 6, 2022_
* Dependencies updated
## v5.4.24 - _July 27, 2022_
* Dependencies updated
## v5.4.23 - _June 14, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-test-utils",
"version": "5.4.33",
"version": "5.4.23",
"engines": {
"node": ">=6.12"
},
@@ -34,7 +34,7 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
"devDependencies": {
"@0x/sol-compiler": "^4.8.2",
"@0x/sol-compiler": "^4.8.1",
"@0x/tslint-config": "^4.1.4",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
@@ -42,20 +42,20 @@
"typescript": "4.6.3"
},
"dependencies": {
"@0x/assert": "^3.0.35",
"@0x/base-contract": "^7.0.0",
"@0x/contract-addresses": "^6.23.2",
"@0x/dev-utils": "^5.0.0",
"@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.46",
"@0x/sol-profiler": "^4.1.36",
"@0x/sol-trace": "^3.0.46",
"@0x/subproviders": "^7.0.0",
"@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": "^7.0.0",
"@0x/web3-wrapper": "^8.0.0",
"@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.7.1",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10",
"ethers": "~4.0.4",
"js-combinatorics": "^0.5.3",

View File

@@ -38,7 +38,7 @@ async function _getGanacheOrGethErrorAsync(ganacheError: string, gethError: stri
}
async function _getInsufficientFundsErrorMessageAsync(): Promise<string> {
return _getGanacheOrGethErrorAsync('insufficient funds for gas * price + value', 'insufficient funds');
return _getGanacheOrGethErrorAsync("sender doesn't have enough funds", 'insufficient funds');
}
async function _getTransactionFailedErrorMessageAsync(): Promise<string> {

View File

@@ -1,94 +1,4 @@
[
{
"timestamp": 1662559804,
"version": "1.4.25",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662147076,
"version": "1.4.24",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662046042,
"version": "1.4.23",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661462289,
"version": "1.4.22",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661459661,
"version": "1.4.21",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661145612,
"version": "1.4.20",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660093941,
"version": "1.4.19",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660073235,
"version": "1.4.18",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1659750766,
"version": "1.4.17",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1658950329,
"version": "1.4.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1655244958,
"version": "1.4.15",

View File

@@ -5,46 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.4.25 - _September 7, 2022_
* Dependencies updated
## v1.4.24 - _September 2, 2022_
* Dependencies updated
## v1.4.23 - _September 1, 2022_
* Dependencies updated
## v1.4.22 - _August 25, 2022_
* Dependencies updated
## v1.4.21 - _August 25, 2022_
* Dependencies updated
## v1.4.20 - _August 22, 2022_
* Dependencies updated
## v1.4.19 - _August 10, 2022_
* Dependencies updated
## v1.4.18 - _August 9, 2022_
* Dependencies updated
## v1.4.17 - _August 6, 2022_
* Dependencies updated
## v1.4.16 - _July 27, 2022_
* Dependencies updated
## v1.4.15 - _June 14, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-treasury",
"version": "1.4.25",
"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.8.1",
"@0x/contract-addresses": "^6.23.2",
"@0x/abi-gen": "^5.8.0",
"@0x/contract-addresses": "^6.16.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.42",
"@0x/contracts-gen": "^2.0.47",
"@0x/contracts-erc20": "^3.3.32",
"@0x/contracts-gen": "^2.0.46",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.33",
"@0x/sol-compiler": "^4.8.2",
"@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",
@@ -72,14 +72,14 @@
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^7.0.0",
"@0x/protocol-utils": "^11.16.9",
"@0x/subproviders": "^7.0.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": "^7.0.0",
"@0x/web3-wrapper": "^8.0.0",
"ethereum-types": "^3.7.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10"
},
"publishConfig": {

View File

@@ -1,94 +1,4 @@
[
{
"timestamp": 1662559804,
"version": "4.8.23",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662147076,
"version": "4.8.22",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662046042,
"version": "4.8.21",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661462289,
"version": "4.8.20",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661459661,
"version": "4.8.19",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661145612,
"version": "4.8.18",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660093941,
"version": "4.8.17",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660073235,
"version": "4.8.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1659750766,
"version": "4.8.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1658950329,
"version": "4.8.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1655244958,
"version": "4.8.13",

View File

@@ -5,46 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.8.23 - _September 7, 2022_
* Dependencies updated
## v4.8.22 - _September 2, 2022_
* Dependencies updated
## v4.8.21 - _September 1, 2022_
* Dependencies updated
## v4.8.20 - _August 25, 2022_
* Dependencies updated
## v4.8.19 - _August 25, 2022_
* Dependencies updated
## v4.8.18 - _August 22, 2022_
* Dependencies updated
## v4.8.17 - _August 10, 2022_
* Dependencies updated
## v4.8.16 - _August 9, 2022_
* Dependencies updated
## v4.8.15 - _August 6, 2022_
* Dependencies updated
## v4.8.14 - _July 27, 2022_
* Dependencies updated
## v4.8.13 - _June 14, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-utils",
"version": "4.8.23",
"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.8.1",
"@0x/contracts-gen": "^2.0.47",
"@0x/contracts-test-utils": "^5.4.33",
"@0x/dev-utils": "^5.0.0",
"@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.8.2",
"@0x/sol-compiler": "^4.8.1",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.6",
"@0x/web3-wrapper": "^8.0.0",
"@0x/web3-wrapper": "^7.6.5",
"@types/bn.js": "^4.11.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -79,11 +79,11 @@
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^7.0.0",
"@0x/base-contract": "^6.5.0",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^7.0.0",
"@0x/utils": "^6.5.3",
"bn.js": "^4.11.8",
"ethereum-types": "^3.7.1"
"ethereum-types": "^3.7.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,101 +1,4 @@
[
{
"timestamp": 1662559804,
"version": "0.37.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1662147076,
"version": "0.37.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.37.0",
"changes": [
{
"note": "Add support for OTC orders in the FillQuoteTransformer",
"pr": "565"
},
{
"note": "fix CI",
"pr": "569"
}
],
"timestamp": 1662046042
},
{
"timestamp": 1661462289,
"version": "0.36.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661459661,
"version": "0.36.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1661145612,
"version": "0.36.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1660093941,
"version": "0.36.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.36.2",
"changes": [
{
"note": "Add Foundry support",
"pr": 534
}
],
"timestamp": 1659976271
},
{
"timestamp": 1659750766,
"version": "0.36.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.36.0",
"changes": [
{
"note": "Add Synthetix support in Ethereum and Optimism bridge adapters",
"pr": 518
}
],
"timestamp": 1658950329
},
{
"version": "0.35.0",
"changes": [

View File

@@ -5,47 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.37.2 - _September 7, 2022_
* Dependencies updated
## v0.37.1 - _September 2, 2022_
* Dependencies updated
## v0.37.0 - _September 1, 2022_
* Add support for OTC orders in the FillQuoteTransformer (#565)
* fix CI (#569)
## v0.36.6 - _August 25, 2022_
* Dependencies updated
## v0.36.5 - _August 25, 2022_
* Dependencies updated
## v0.36.4 - _August 22, 2022_
* Dependencies updated
## v0.36.3 - _August 10, 2022_
* Dependencies updated
## v0.36.2 - _August 8, 2022_
* Add Foundry support (#534)
## v0.36.1 - _August 6, 2022_
* Dependencies updated
## v0.36.0 - _July 27, 2022_
* Add Synthetix support in Ethereum and Optimism bridge adapters (#518)
## v0.35.0 - _June 14, 2022_
* Adds support for Velodrome OptimismBridgeAdapter (#494)

View File

@@ -2,10 +2,6 @@
This package contains contracts for the ZeroEx extensible contract architecture.
> **_NOTE:_** This repo is undergoing a tooling change. If adding a contract, you will need to
> add it to `compiler.json`. You can generate the entire list by running the following:
> `find . -type f -name "*.sol" | grep -v foundry | grep -v "contracts/dep" | grep -v "node_modules"`
## Installation
**Install**

View File

@@ -1,212 +1,6 @@
{
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"contracts": [
"./contracts/src/IZeroEx.sol",
"./contracts/src/ZeroEx.sol",
"./contracts/src/ZeroExOptimized.sol",
"./contracts/src/errors/LibCommonRichErrors.sol",
"./contracts/src/errors/LibLiquidityProviderRichErrors.sol",
"./contracts/src/errors/LibMetaTransactionsRichErrors.sol",
"./contracts/src/errors/LibNFTOrdersRichErrors.sol",
"./contracts/src/errors/LibNativeOrdersRichErrors.sol",
"./contracts/src/errors/LibOwnableRichErrors.sol",
"./contracts/src/errors/LibProxyRichErrors.sol",
"./contracts/src/errors/LibSignatureRichErrors.sol",
"./contracts/src/errors/LibSimpleFunctionRegistryRichErrors.sol",
"./contracts/src/errors/LibTransformERC20RichErrors.sol",
"./contracts/src/errors/LibWalletRichErrors.sol",
"./contracts/src/external/FeeCollector.sol",
"./contracts/src/external/FeeCollectorController.sol",
"./contracts/src/external/FlashWallet.sol",
"./contracts/src/external/IFlashWallet.sol",
"./contracts/src/external/ILiquidityProviderSandbox.sol",
"./contracts/src/external/LibFeeCollector.sol",
"./contracts/src/external/LiquidityProviderSandbox.sol",
"./contracts/src/external/PermissionlessTransformerDeployer.sol",
"./contracts/src/external/TransformerDeployer.sol",
"./contracts/src/features/BatchFillNativeOrdersFeature.sol",
"./contracts/src/features/BootstrapFeature.sol",
"./contracts/src/features/ERC165Feature.sol",
"./contracts/src/features/FundRecoveryFeature.sol",
"./contracts/src/features/LiquidityProviderFeature.sol",
"./contracts/src/features/MetaTransactionsFeature.sol",
"./contracts/src/features/NativeOrdersFeature.sol",
"./contracts/src/features/OtcOrdersFeature.sol",
"./contracts/src/features/OwnableFeature.sol",
"./contracts/src/features/PancakeSwapFeature.sol",
"./contracts/src/features/SimpleFunctionRegistryFeature.sol",
"./contracts/src/features/TransformERC20Feature.sol",
"./contracts/src/features/UniswapFeature.sol",
"./contracts/src/features/UniswapV3Feature.sol",
"./contracts/src/features/interfaces/IBatchFillNativeOrdersFeature.sol",
"./contracts/src/features/interfaces/IBootstrapFeature.sol",
"./contracts/src/features/interfaces/IERC1155OrdersFeature.sol",
"./contracts/src/features/interfaces/IERC165Feature.sol",
"./contracts/src/features/interfaces/IERC721OrdersFeature.sol",
"./contracts/src/features/interfaces/IFeature.sol",
"./contracts/src/features/interfaces/IFundRecoveryFeature.sol",
"./contracts/src/features/interfaces/ILiquidityProviderFeature.sol",
"./contracts/src/features/interfaces/IMetaTransactionsFeature.sol",
"./contracts/src/features/interfaces/IMultiplexFeature.sol",
"./contracts/src/features/interfaces/INativeOrdersEvents.sol",
"./contracts/src/features/interfaces/INativeOrdersFeature.sol",
"./contracts/src/features/interfaces/IOtcOrdersFeature.sol",
"./contracts/src/features/interfaces/IOwnableFeature.sol",
"./contracts/src/features/interfaces/IPancakeSwapFeature.sol",
"./contracts/src/features/interfaces/ISimpleFunctionRegistryFeature.sol",
"./contracts/src/features/interfaces/ITokenSpenderFeature.sol",
"./contracts/src/features/interfaces/ITransformERC20Feature.sol",
"./contracts/src/features/interfaces/IUniswapFeature.sol",
"./contracts/src/features/interfaces/IUniswapV3Feature.sol",
"./contracts/src/features/libs/LibNFTOrder.sol",
"./contracts/src/features/libs/LibNativeOrder.sol",
"./contracts/src/features/libs/LibSignature.sol",
"./contracts/src/features/multiplex/MultiplexFeature.sol",
"./contracts/src/features/multiplex/MultiplexLiquidityProvider.sol",
"./contracts/src/features/multiplex/MultiplexOtc.sol",
"./contracts/src/features/multiplex/MultiplexRfq.sol",
"./contracts/src/features/multiplex/MultiplexTransformERC20.sol",
"./contracts/src/features/multiplex/MultiplexUniswapV2.sol",
"./contracts/src/features/multiplex/MultiplexUniswapV3.sol",
"./contracts/src/features/native_orders/NativeOrdersCancellation.sol",
"./contracts/src/features/native_orders/NativeOrdersInfo.sol",
"./contracts/src/features/native_orders/NativeOrdersProtocolFees.sol",
"./contracts/src/features/native_orders/NativeOrdersSettlement.sol",
"./contracts/src/features/nft_orders/ERC1155OrdersFeature.sol",
"./contracts/src/features/nft_orders/ERC721OrdersFeature.sol",
"./contracts/src/features/nft_orders/NFTOrders.sol",
"./contracts/src/fixins/FixinCommon.sol",
"./contracts/src/fixins/FixinEIP712.sol",
"./contracts/src/fixins/FixinERC1155Spender.sol",
"./contracts/src/fixins/FixinERC721Spender.sol",
"./contracts/src/fixins/FixinProtocolFees.sol",
"./contracts/src/fixins/FixinReentrancyGuard.sol",
"./contracts/src/fixins/FixinTokenSpender.sol",
"./contracts/src/liquidity-providers/CurveLiquidityProvider.sol",
"./contracts/src/liquidity-providers/MooniswapLiquidityProvider.sol",
"./contracts/src/migrations/FullMigration.sol",
"./contracts/src/migrations/InitialMigration.sol",
"./contracts/src/migrations/LibBootstrap.sol",
"./contracts/src/migrations/LibMigrate.sol",
"./contracts/src/storage/LibERC1155OrdersStorage.sol",
"./contracts/src/storage/LibERC721OrdersStorage.sol",
"./contracts/src/storage/LibMetaTransactionsStorage.sol",
"./contracts/src/storage/LibNativeOrdersStorage.sol",
"./contracts/src/storage/LibOtcOrdersStorage.sol",
"./contracts/src/storage/LibOwnableStorage.sol",
"./contracts/src/storage/LibProxyStorage.sol",
"./contracts/src/storage/LibReentrancyGuardStorage.sol",
"./contracts/src/storage/LibSimpleFunctionRegistryStorage.sol",
"./contracts/src/storage/LibStorage.sol",
"./contracts/src/storage/LibTransformERC20Storage.sol",
"./contracts/src/transformers/AffiliateFeeTransformer.sol",
"./contracts/src/transformers/FillQuoteTransformer.sol",
"./contracts/src/transformers/IERC20Transformer.sol",
"./contracts/src/transformers/LibERC20Transformer.sol",
"./contracts/src/transformers/LogMetadataTransformer.sol",
"./contracts/src/transformers/PayTakerTransformer.sol",
"./contracts/src/transformers/PositiveSlippageFeeTransformer.sol",
"./contracts/src/transformers/Transformer.sol",
"./contracts/src/transformers/WethTransformer.sol",
"./contracts/src/transformers/bridges/AbstractBridgeAdapter.sol",
"./contracts/src/transformers/bridges/AvalancheBridgeAdapter.sol",
"./contracts/src/transformers/bridges/BSCBridgeAdapter.sol",
"./contracts/src/transformers/bridges/BridgeProtocols.sol",
"./contracts/src/transformers/bridges/CeloBridgeAdapter.sol",
"./contracts/src/transformers/bridges/EthereumBridgeAdapter.sol",
"./contracts/src/transformers/bridges/FantomBridgeAdapter.sol",
"./contracts/src/transformers/bridges/IBridgeAdapter.sol",
"./contracts/src/transformers/bridges/OptimismBridgeAdapter.sol",
"./contracts/src/transformers/bridges/PolygonBridgeAdapter.sol",
"./contracts/src/transformers/bridges/mixins/MixinAaveV2.sol",
"./contracts/src/transformers/bridges/mixins/MixinBalancer.sol",
"./contracts/src/transformers/bridges/mixins/MixinBalancerV2.sol",
"./contracts/src/transformers/bridges/mixins/MixinBalancerV2Batch.sol",
"./contracts/src/transformers/bridges/mixins/MixinBancor.sol",
"./contracts/src/transformers/bridges/mixins/MixinBancorV3.sol",
"./contracts/src/transformers/bridges/mixins/MixinCompound.sol",
"./contracts/src/transformers/bridges/mixins/MixinCryptoCom.sol",
"./contracts/src/transformers/bridges/mixins/MixinCurve.sol",
"./contracts/src/transformers/bridges/mixins/MixinCurveV2.sol",
"./contracts/src/transformers/bridges/mixins/MixinDodo.sol",
"./contracts/src/transformers/bridges/mixins/MixinDodoV2.sol",
"./contracts/src/transformers/bridges/mixins/MixinGMX.sol",
"./contracts/src/transformers/bridges/mixins/MixinKyberDmm.sol",
"./contracts/src/transformers/bridges/mixins/MixinLido.sol",
"./contracts/src/transformers/bridges/mixins/MixinMStable.sol",
"./contracts/src/transformers/bridges/mixins/MixinMakerPSM.sol",
"./contracts/src/transformers/bridges/mixins/MixinMooniswap.sol",
"./contracts/src/transformers/bridges/mixins/MixinNerve.sol",
"./contracts/src/transformers/bridges/mixins/MixinPlatypus.sol",
"./contracts/src/transformers/bridges/mixins/MixinShell.sol",
"./contracts/src/transformers/bridges/mixins/MixinSynthetix.sol",
"./contracts/src/transformers/bridges/mixins/MixinUniswap.sol",
"./contracts/src/transformers/bridges/mixins/MixinUniswapV2.sol",
"./contracts/src/transformers/bridges/mixins/MixinUniswapV3.sol",
"./contracts/src/transformers/bridges/mixins/MixinVelodrome.sol",
"./contracts/src/transformers/bridges/mixins/MixinZeroExBridge.sol",
"./contracts/src/vendor/IERC1155Token.sol",
"./contracts/src/vendor/IERC721Token.sol",
"./contracts/src/vendor/IFeeRecipient.sol",
"./contracts/src/vendor/ILiquidityProvider.sol",
"./contracts/src/vendor/IMooniswapPool.sol",
"./contracts/src/vendor/IPropertyValidator.sol",
"./contracts/src/vendor/ITakerCallback.sol",
"./contracts/src/vendor/IUniswapV2Pair.sol",
"./contracts/src/vendor/IUniswapV3Pool.sol",
"./contracts/src/vendor/v3/IERC20Bridge.sol",
"./contracts/src/vendor/v3/IStaking.sol",
"./contracts/test/ITestSimpleFunctionRegistryFeature.sol",
"./contracts/test/TestBridge.sol",
"./contracts/test/TestCallTarget.sol",
"./contracts/test/TestDelegateCaller.sol",
"./contracts/test/TestFeeCollectorController.sol",
"./contracts/test/TestFeeRecipient.sol",
"./contracts/test/TestFillQuoteTransformerBridge.sol",
"./contracts/test/TestFillQuoteTransformerExchange.sol",
"./contracts/test/TestFillQuoteTransformerHost.sol",
"./contracts/test/TestFixinProtocolFees.sol",
"./contracts/test/TestFixinTokenSpender.sol",
"./contracts/test/TestFullMigration.sol",
"./contracts/test/TestInitialMigration.sol",
"./contracts/test/TestLibNativeOrder.sol",
"./contracts/test/TestLibSignature.sol",
"./contracts/test/TestMetaTransactionsNativeOrdersFeature.sol",
"./contracts/test/TestMetaTransactionsTransformERC20Feature.sol",
"./contracts/test/TestMigrator.sol",
"./contracts/test/TestMintTokenERC20Transformer.sol",
"./contracts/test/TestNFTOrderPresigner.sol",
"./contracts/test/TestNativeOrdersFeature.sol",
"./contracts/test/TestNoEthRecipient.sol",
"./contracts/test/TestOrderSignerRegistryWithContractWallet.sol",
"./contracts/test/TestPermissionlessTransformerDeployerSuicidal.sol",
"./contracts/test/TestPermissionlessTransformerDeployerTransformer.sol",
"./contracts/test/TestPropertyValidator.sol",
"./contracts/test/TestRfqOriginRegistration.sol",
"./contracts/test/TestSimpleFunctionRegistryFeatureImpl1.sol",
"./contracts/test/TestSimpleFunctionRegistryFeatureImpl2.sol",
"./contracts/test/TestStaking.sol",
"./contracts/test/TestTransformERC20.sol",
"./contracts/test/TestTransformerBase.sol",
"./contracts/test/TestTransformerDeployerTransformer.sol",
"./contracts/test/TestTransformerHost.sol",
"./contracts/test/TestUniswapV3Feature.sol",
"./contracts/test/TestWethTransformerHost.sol",
"./contracts/test/TestZeroExFeature.sol",
"./contracts/test/integration/TestCurve.sol",
"./contracts/test/integration/TestLiquidityProvider.sol",
"./contracts/test/integration/TestMooniswap.sol",
"./contracts/test/integration/TestUniswapV2Factory.sol",
"./contracts/test/integration/TestUniswapV2Pool.sol",
"./contracts/test/integration/TestUniswapV3Factory.sol",
"./contracts/test/integration/TestUniswapV3Pool.sol",
"./contracts/test/tokens/TestMintableERC1155Token.sol",
"./contracts/test/tokens/TestMintableERC20Token.sol",
"./contracts/test/tokens/TestMintableERC721Token.sol",
"./contracts/test/tokens/TestTokenSpenderERC20Token.sol",
"./contracts/test/tokens/TestWeth.sol"
],
"useDockerisedSolc": false,
"isOfflineMode": false,
"shouldSaveStandardInput": true,

View File

@@ -93,10 +93,10 @@ contract FillQuoteTransformer is
IBridgeAdapter.BridgeOrder[] bridgeOrders;
// Native limit orders. Sorted by fill sequence.
LimitOrderInfo[] limitOrders;
// Otc orders. Sorted by fill sequence.
OtcOrderInfo[] otcOrders;
// Native RFQ orders. Sorted by fill sequence.
RfqOrderInfo[] rfqOrders;
// Otc orders. Sorted by fill sequence.
OtcOrderInfo[] otcOrders;
// The sequence to fill the orders in. Each item will fill the next
// order of that type in either `bridgeOrders`, `limitOrders`,
@@ -213,12 +213,13 @@ contract FillQuoteTransformer is
if (data.limitOrders.length + data.rfqOrders.length + data.otcOrders.length != 0) {
data.sellToken.approveIfBelow(address(zeroEx), data.fillAmount);
// Compute the protocol fee if a limit order is present.
if (data.limitOrders.length != 0) {
state.protocolFee = uint256(zeroEx.getProtocolFeeMultiplier())
.safeMul(tx.gasprice);
}
}
state.ethRemaining = address(this).balance;
// Fill the orders.
@@ -234,6 +235,7 @@ contract FillQuoteTransformer is
state.currentOrderType = OrderType(data.fillSequence[i]);
uint256 orderIndex = state.currentIndices[uint256(state.currentOrderType)];
// Fill the order.
FillOrderResults memory results;
if (state.currentOrderType == OrderType.Bridge) {
@@ -327,7 +329,7 @@ contract FillQuoteTransformer is
if (success) {
results.makerTokenBoughtAmount = abi.decode(resultData, (uint256));
results.takerTokenSoldAmount = takerTokenFillAmount;
}
}
}
// Fill a single limit order.
@@ -416,7 +418,7 @@ contract FillQuoteTransformer is
} catch {}
}
// Fill a single OTC order.
// Fill a single RFQ order.
function _fillOtcOrder(
OtcOrderInfo memory orderInfo,
TransformData memory data,
@@ -425,7 +427,6 @@ contract FillQuoteTransformer is
private
returns (FillOrderResults memory results)
{
uint256 takerTokenFillAmount = LibSafeMathV06.min256(
_computeTakerTokenFillAmount(
data,

View File

@@ -1,113 +0,0 @@
// 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/MixinBalancerV2.sol";
import "./mixins/MixinCurve.sol";
import "./mixins/MixinDodoV2.sol";
import "./mixins/MixinGMX.sol";
import "./mixins/MixinUniswapV3.sol";
import "./mixins/MixinZeroExBridge.sol";
contract ArbitrumBridgeAdapter is
AbstractBridgeAdapter(42161, "Arbitrum"),
MixinBalancerV2,
MixinCurve,
MixinDodoV2,
MixinGMX,
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.BALANCERV2) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeBalancerV2(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.CURVE) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeCurve(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.DODOV2) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeDodoV2(
sellToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNISWAPV3) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeUniswapV3(
sellToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.GMX) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeGMX(
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
);
}
}

View File

@@ -30,7 +30,6 @@ import "./mixins/MixinAaveV2.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinPlatypus.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinWOOFi.sol";
import "./mixins/MixinZeroExBridge.sol";
contract AvalancheBridgeAdapter is
@@ -43,7 +42,6 @@ contract AvalancheBridgeAdapter is
MixinNerve,
MixinPlatypus,
MixinUniswapV2,
MixinWOOFi,
MixinZeroExBridge
{
constructor(IEtherTokenV06 weth)
@@ -122,14 +120,6 @@ contract AvalancheBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.WOOFI) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeWOOFi(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNKNOWN) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeZeroExBridge(

View File

@@ -29,7 +29,6 @@ import "./mixins/MixinKyberDmm.sol";
import "./mixins/MixinMooniswap.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinWOOFi.sol";
import "./mixins/MixinZeroExBridge.sol";
contract BSCBridgeAdapter is
@@ -41,7 +40,6 @@ contract BSCBridgeAdapter is
MixinMooniswap,
MixinNerve,
MixinUniswapV2,
MixinWOOFi,
MixinZeroExBridge
{
constructor(IEtherTokenV06 weth)
@@ -113,14 +111,6 @@ contract BSCBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.WOOFI) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeWOOFi(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNKNOWN) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeZeroExBridge(

View File

@@ -57,6 +57,4 @@ library BridgeProtocols {
uint128 internal constant PLATYPUS = 27;
uint128 internal constant BANCORV3 = 28;
uint128 internal constant VELODROME = 29;
uint128 internal constant SYNTHETIX = 30;
uint128 internal constant WOOFI = 31;
}

View File

@@ -37,10 +37,10 @@ import "./mixins/MixinDodoV2.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/MixinShell.sol";
import "./mixins/MixinSynthetix.sol";
import "./mixins/MixinUniswap.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinUniswapV3.sol";
@@ -63,10 +63,10 @@ contract EthereumBridgeAdapter is
MixinKyberDmm,
MixinLido,
MixinMakerPSM,
MixinMooniswap,
MixinMStable,
MixinNerve,
MixinShell,
MixinSynthetix,
MixinUniswap,
MixinUniswapV2,
MixinUniswapV3,
@@ -79,6 +79,7 @@ contract EthereumBridgeAdapter is
MixinCompound(weth)
MixinCurve(weth)
MixinLido(weth)
MixinMooniswap(weth)
MixinUniswap(weth)
{}
@@ -162,6 +163,14 @@ contract EthereumBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.MOONISWAP) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeMooniswap(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.MSTABLE) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeMStable(
@@ -251,12 +260,6 @@ contract EthereumBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.SYNTHETIX) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeSynthetix(
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNKNOWN) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeZeroExBridge(

View File

@@ -28,7 +28,6 @@ import "./mixins/MixinCurve.sol";
import "./mixins/MixinCurveV2.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinWOOFi.sol";
import "./mixins/MixinZeroExBridge.sol";
contract FantomBridgeAdapter is
@@ -39,7 +38,6 @@ contract FantomBridgeAdapter is
MixinCurveV2,
MixinNerve,
MixinUniswapV2,
MixinWOOFi,
MixinZeroExBridge
{
constructor(IEtherTokenV06 weth)
@@ -105,14 +103,6 @@ contract FantomBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.WOOFI) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeWOOFi(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNKNOWN) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeZeroExBridge(

View File

@@ -25,7 +25,6 @@ import "./BridgeProtocols.sol";
import "./mixins/MixinCurve.sol";
import "./mixins/MixinCurveV2.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinSynthetix.sol";
import "./mixins/MixinUniswapV3.sol";
import "./mixins/MixinVelodrome.sol";
import "./mixins/MixinZeroExBridge.sol";
@@ -35,7 +34,6 @@ contract OptimismBridgeAdapter is
MixinCurve,
MixinCurveV2,
MixinNerve,
MixinSynthetix,
MixinUniswapV3,
MixinVelodrome,
MixinZeroExBridge
@@ -95,12 +93,6 @@ contract OptimismBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.SYNTHETIX) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeSynthetix(
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNKNOWN) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeZeroExBridge(

View File

@@ -34,7 +34,6 @@ import "./mixins/MixinMStable.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinUniswapV3.sol";
import "./mixins/MixinWOOFi.sol";
import "./mixins/MixinZeroExBridge.sol";
contract PolygonBridgeAdapter is
@@ -51,7 +50,6 @@ contract PolygonBridgeAdapter is
MixinNerve,
MixinUniswapV2,
MixinUniswapV3,
MixinWOOFi,
MixinZeroExBridge
{
constructor(IEtherTokenV06 weth)
@@ -159,14 +157,6 @@ contract PolygonBridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.WOOFI) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeWOOFi(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNKNOWN) {
if (dryRun) { return (0, true); }
boughtAmount = _tradeZeroExBridge(

View File

@@ -1,99 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2022 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
interface ISynthetix {
// Ethereum Mainnet
function exchangeAtomically(
bytes32 sourceCurrencyKey,
uint256 sourceAmount,
bytes32 destinationCurrencyKey,
bytes32 trackingCode,
uint256 minAmount
) external returns (uint256 amountReceived);
// Optimism
function exchangeWithTracking(
bytes32 sourceCurrencyKey,
uint256 sourceAmount,
bytes32 destinationCurrencyKey,
address rewardAddress,
bytes32 trackingCode
) external returns (uint256 amountReceived);
}
contract MixinSynthetix {
address private constant rewardAddress =
0x5C80239D97E1eB216b5c3D8fBa5DE5Be5d38e4C9;
bytes32 constant trackingCode =
0x3058000000000000000000000000000000000000000000000000000000000000;
function _tradeSynthetix(uint256 sellAmount, bytes memory bridgeData)
public
returns (uint256 boughtAmount)
{
(
ISynthetix synthetix,
bytes32 sourceCurrencyKey,
bytes32 destinationCurrencyKey
) = abi.decode(
bridgeData,
(ISynthetix, bytes32, bytes32)
);
boughtAmount = exchange(
synthetix,
sourceCurrencyKey,
destinationCurrencyKey,
sellAmount
);
}
function exchange(
ISynthetix synthetix,
bytes32 sourceCurrencyKey,
bytes32 destinationCurrencyKey,
uint256 sellAmount
) internal returns (uint256 boughtAmount) {
uint256 chainId;
assembly {
chainId := chainid()
}
if (chainId == 1) {
boughtAmount = synthetix.exchangeAtomically(
sourceCurrencyKey,
sellAmount,
destinationCurrencyKey,
trackingCode,
0
);
} else {
boughtAmount = synthetix.exchangeWithTracking(
sourceCurrencyKey,
sellAmount,
destinationCurrencyKey,
rewardAddress,
trackingCode
);
}
}
}

View File

@@ -1,136 +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 "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "../IBridgeAdapter.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
/// @dev WooFI pool interface.
interface IWooPP {
function quoteToken() external view returns (address);
function sellBase(
address baseToken,
uint256 baseAmount,
uint256 minQuoteAmount,
address to,
address rebateTo
) external returns (uint256 quoteAmount);
function sellQuote(
address baseToken,
uint256 quoteAmount,
uint256 minBaseAmount,
address to,
address rebateTo
) external returns (uint256 baseAmount);
/// @dev Query the amount for selling the base token amount.
/// @param baseToken the base token to sell
/// @param baseAmount the amount to sell
/// @return quoteAmount the swapped quote amount
function querySellBase(
address baseToken,
uint256 baseAmount
) external view returns (uint256 quoteAmount);
}
contract MixinWOOFi{
using LibERC20TokenV06 for IERC20TokenV06;
using LibERC20TokenV06 for IEtherTokenV06;
using LibSafeMathV06 for uint256;
address constant rebateAddress = 0xBfdcBB4C05843163F491C24f9c0019c510786304;
// /// @dev Swaps an exact amount of input tokens for as many output tokens as possible.
// /// @param _amountIn Amount of input tokens to send
// /// @param _minAmountOut The minimum amount of output tokens that must be received for the transaction not to revert.
// /// @param _tokenIn Input token
// /// @param _tokenOut Output token
// /// @param _to recipient of tokens
// /// @param pool WOOFi pool where the swap will happen
function _tradeWOOFi(
IERC20TokenV06 sellToken,
IERC20TokenV06 buyToken,
uint256 sellAmount,
bytes memory bridgeData
)
public
returns (uint256 boughtAmount)
{
(IWooPP _pool) = abi.decode(bridgeData, (IWooPP));
uint256 beforeBalance = buyToken.balanceOf(address(this));
sellToken.approveIfBelow(address(_pool), sellAmount);
_swap(
sellAmount,
address(sellToken),
address(buyToken),
_pool
);
boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance);
}
function _swap(
uint _amountIn,
address _tokenIn,
address _tokenOut,
IWooPP pool
) internal {
address quoteToken = pool.quoteToken();
if (_tokenIn == quoteToken) {
pool.sellQuote(
_tokenOut,
_amountIn,
1,
address(this),
rebateAddress
);
} else if (_tokenOut == quoteToken) {
pool.sellBase(
_tokenIn,
_amountIn,
1,
address(this),
rebateAddress
);
} else {
uint256 quoteAmount = pool.sellBase(
_tokenIn,
_amountIn,
0,
address(this),
rebateAddress
);
IERC20TokenV06(pool.quoteToken()).approveIfBelow(address(pool), quoteAmount);
pool.sellQuote(
_tokenOut,
quoteAmount,
1,
address(this),
rebateAddress
);
}
}
}

View File

@@ -1,30 +0,0 @@
// 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;
import "forge-std/Test.sol";
contract ContractTest is Test {
function setUp() public {}
function testExample() public {
assertTrue(true);
}
}

View File

@@ -1,8 +0,0 @@
[default]
src = 'contracts/src'
out = 'foundry-artifacts'
test = 'contracts/test/foundry'
libs = ["contracts/deps/", "../utils/contracts/src/"]
remappings = ['@0x/contracts-utils/=../utils/', '@0x/contracts-erc20/=../erc20/', 'src/=./contracts/src']
cache_path = 'foundry-cache'
optimizer_runs = 1000000

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-zero-ex",
"version": "0.37.2",
"version": "0.35.0",
"engines": {
"node": ">=6.12"
},
@@ -38,13 +38,12 @@
"docs:md": "ts-doc-gen --sourceDir='$PROJECT_FILES' --output=$MD_FILE_DIR --fileExtension=mdx --tsconfig=./typedoc-tsconfig.json",
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES",
"publish:private": "yarn build && gitpkg publish",
"rollback": "node ./lib/scripts/rollback.js",
"typechain": "typechain --target=ethers-v5 --out-dir='typechain-wrappers' './foundry-artifacts/**/*.json'"
"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,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/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinSynthetix|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinVelodrome|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"
"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",
@@ -56,17 +55,16 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
"devDependencies": {
"@0x/abi-gen": "^5.8.1",
"@0x/contract-addresses": "^6.23.2",
"@0x/contracts-erc20": "^3.3.42",
"@0x/contracts-gen": "^2.0.47",
"@0x/contracts-test-utils": "^5.4.33",
"@0x/dev-utils": "^5.0.0",
"@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.8.2",
"@0x/sol-compiler": "^4.8.1",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@typechain/ethers-v5": "^10.0.0",
"@types/isomorphic-fetch": "^0.0.35",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -80,19 +78,18 @@
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typechain": "^8.0.0",
"typedoc": "~0.16.11",
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^7.0.0",
"@0x/protocol-utils": "^11.16.9",
"@0x/subproviders": "^7.0.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": "^7.0.0",
"@0x/web3-wrapper": "^8.0.0",
"ethereum-types": "^3.7.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"
},

View File

@@ -124,7 +124,6 @@ import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json';
import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json';
import * as MixinPlatypus from '../test/generated-artifacts/MixinPlatypus.json';
import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
import * as MixinSynthetix from '../test/generated-artifacts/MixinSynthetix.json';
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json';
import * as MixinUniswapV3 from '../test/generated-artifacts/MixinUniswapV3.json';
@@ -348,7 +347,6 @@ export const artifacts = {
MixinNerve: MixinNerve as ContractArtifact,
MixinPlatypus: MixinPlatypus as ContractArtifact,
MixinShell: MixinShell as ContractArtifact,
MixinSynthetix: MixinSynthetix as ContractArtifact,
MixinUniswap: MixinUniswap as ContractArtifact,
MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
MixinUniswapV3: MixinUniswapV3 as ContractArtifact,

View File

@@ -30,7 +30,7 @@ blockchainTests.resets('MetaTransactions feature', env => {
let maker: string;
let sender: string;
let notSigner: string;
const signers: string[] = [];
let signers: string[];
let zeroEx: IZeroExContract;
let feature: MetaTransactionsFeatureContract;
let feeToken: TestMintableERC20TokenContract;
@@ -45,8 +45,7 @@ blockchainTests.resets('MetaTransactions feature', env => {
const REENTRANCY_FLAG_MTX = 0x1;
before(async () => {
let possibleSigners: string[];
[owner, maker, sender, notSigner, ...possibleSigners] = await env.getAccountAddressesAsync();
[owner, maker, sender, notSigner, ...signers] = await env.getAccountAddressesAsync();
transformERC20Feature = await TestMetaTransactionsTransformERC20FeatureContract.deployFrom0xArtifactAsync(
artifacts.TestMetaTransactionsTransformERC20Feature,
env.provider,
@@ -75,26 +74,20 @@ blockchainTests.resets('MetaTransactions feature', env => {
env.txDefaults,
{},
);
// some accounts returned can be unfunded
for (const possibleSigner of possibleSigners) {
const balance = await env.web3Wrapper.getBalanceInWeiAsync(possibleSigner);
if (balance.isGreaterThan(0)) {
signers.push(possibleSigner);
await feeToken
.approve(zeroEx.address, MAX_FEE_AMOUNT)
.awaitTransactionSuccessAsync({ from: possibleSigner });
await feeToken.mint(possibleSigner, MAX_FEE_AMOUNT).awaitTransactionSuccessAsync();
}
}
// Fund signers with fee tokens.
await Promise.all(
signers.map(async signer => {
await feeToken.mint(signer, MAX_FEE_AMOUNT).awaitTransactionSuccessAsync();
await feeToken.approve(zeroEx.address, MAX_FEE_AMOUNT).awaitTransactionSuccessAsync({ from: signer });
}),
);
});
function getRandomMetaTransaction(fields: Partial<MetaTransactionFields> = {}): MetaTransaction {
return new MetaTransaction({
signer: _.sampleSize(signers)[0],
sender,
// TODO: dekz Ganache gasPrice opcode is returning 0, cannot influence it up to test this case
minGasPrice: ZERO_AMOUNT,
minGasPrice: getRandomInteger('2', '1e9'),
maxGasPrice: getRandomInteger('1e9', '100e9'),
expirationTimeSeconds: new BigNumber(Math.floor(_.now() / 1000) + 360),
salt: new BigNumber(hexUtils.random()),
@@ -152,7 +145,6 @@ blockchainTests.resets('MetaTransactions feature', env => {
gasPrice: mtx.minGasPrice,
value: mtx.value,
};
const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts);
expect(rawResult).to.eq(RAW_ORDER_SUCCESS_RESULT);
const receipt = await feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts);
@@ -442,8 +434,7 @@ blockchainTests.resets('MetaTransactions feature', env => {
);
});
// Ganache gasPrice opcode is returning 0, cannot influence it up to test this case
it.skip('fails if gas price too low', async () => {
it('fails if gas price too low', async () => {
const mtx = getRandomMetaTransaction();
const mtxHash = mtx.getHash();
const signature = await mtx.getSignatureWithProviderAsync(env.provider);
@@ -462,8 +453,7 @@ blockchainTests.resets('MetaTransactions feature', env => {
);
});
// Ganache gasPrice opcode is returning 0, cannot influence it up to test this case
it.skip('fails if gas price too high', async () => {
it('fails if gas price too high', async () => {
const mtx = getRandomMetaTransaction();
const mtxHash = mtx.getHash();
const signature = await mtx.getSignatureWithProviderAsync(env.provider);

View File

@@ -938,8 +938,7 @@ blockchainTests.resets('NativeOrdersFeature', env => {
);
});
// TODO: dekz Ganache gasPrice opcode is returning 0, cannot influence it up to test this case
it.skip('fails if no protocol fee attached', async () => {
it('fails if no protocol fee attached', async () => {
const order = getTestLimitOrder();
await testUtils.prepareBalancesForOrdersAsync([order]);
const tx = zeroEx

View File

@@ -10,8 +10,7 @@ import {
TestWethContract,
} from './wrappers';
// TODO: dekz Ganache gasPrice opcode is returning 0, cannot influence it up to test this case
blockchainTests.resets.skip('ProtocolFees', env => {
blockchainTests.resets('ProtocolFees', env => {
const FEE_MULTIPLIER = 70e3;
let taker: string;
let unauthorized: string;
@@ -63,7 +62,7 @@ blockchainTests.resets.skip('ProtocolFees', env => {
it('should disallow unauthorized initialization', async () => {
const pool = hexUtils.random();
await protocolFees.collectProtocolFee(pool).awaitTransactionSuccessAsync({ value: 1e9 });
await protocolFees.collectProtocolFee(pool).awaitTransactionSuccessAsync({ value: singleFeeAmount });
await protocolFees.transferFeesForPool(pool).awaitTransactionSuccessAsync();
const feeCollector = new FeeCollectorContract(
@@ -90,7 +89,6 @@ blockchainTests.resets.skip('ProtocolFees', env => {
feeCollector2Address = await protocolFees.getFeeCollector(pool2).callAsync();
});
// Ganache gasPrice opcode is returning 0, cannot influence it up to test this case
it('should revert if insufficient ETH transferred', async () => {
const tooLittle = singleFeeAmount.minus(1);
const tx = protocolFees.collectProtocolFee(pool1).awaitTransactionSuccessAsync({ value: tooLittle });

View File

@@ -12,10 +12,13 @@ import {
FillQuoteTransformerData,
FillQuoteTransformerLimitOrderInfo,
FillQuoteTransformerOrderType as OrderType,
FillQuoteTransformerOtcOrderInfo,
FillQuoteTransformerRfqOrderInfo,
FillQuoteTransformerSide as Side,
LimitOrder,
LimitOrderFields,
OtcOrder,
OtcOrderFields,
RfqOrder,
RfqOrderFields,
Signature,
@@ -26,7 +29,7 @@ import * as _ from 'lodash';
import { artifacts } from '../artifacts';
import { TestFillQuoteTransformerBridgeContract } from '../generated-wrappers/test_fill_quote_transformer_bridge';
import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders';
import { getRandomLimitOrder, getRandomOtcOrder, getRandomRfqOrder } from '../utils/orders';
import {
EthereumBridgeAdapterContract,
FillQuoteTransformerContract,
@@ -142,6 +145,18 @@ blockchainTests.resets('FillQuoteTransformer', env => {
};
}
function createOtcOrder(fields: Partial<OtcOrderFields> = {}): OtcOrder {
return getRandomOtcOrder({
makerToken: makerToken.address,
takerToken: takerToken.address,
makerAmount: getRandomInteger('0.1e18', '1e18'),
takerAmount: getRandomInteger('0.1e18', '1e18'),
maker,
taker,
...fields,
});
}
function createOrderSignature(preFilledTakerAmount: Numberish = 0): Signature {
return {
// The r field of the signature is the pre-filled amount.
@@ -254,6 +269,24 @@ blockchainTests.resets('FillQuoteTransformer', env => {
};
}
function fillOtcOrder(oi: FillQuoteTransformerOtcOrderInfo): FillOrderResults {
const preFilledTakerAmount = orderSignatureToPreFilledTakerAmount(oi.signature);
if (preFilledTakerAmount.gte(oi.order.takerAmount) || preFilledTakerAmount.eq(REVERT_AMOUNT)) {
return EMPTY_FILL_ORDER_RESULTS;
}
const takerTokenFillAmount = BigNumber.min(
computeTakerTokenFillAmount(oi.order.takerAmount, oi.order.makerAmount),
oi.order.takerAmount.minus(preFilledTakerAmount),
oi.maxTakerTokenFillAmount,
);
const fillRatio = takerTokenFillAmount.div(oi.order.takerAmount);
return {
...EMPTY_FILL_ORDER_RESULTS,
takerTokenSoldAmount: takerTokenFillAmount,
makerTokenBoughtAmount: fillRatio.times(oi.order.makerAmount).integerValue(BigNumber.ROUND_DOWN),
};
}
function fillRfqOrder(oi: FillQuoteTransformerRfqOrderInfo): FillOrderResults {
const preFilledTakerAmount = orderSignatureToPreFilledTakerAmount(oi.signature);
if (preFilledTakerAmount.gte(oi.order.takerAmount) || preFilledTakerAmount.eq(REVERT_AMOUNT)) {
@@ -296,6 +329,11 @@ blockchainTests.resets('FillQuoteTransformer', env => {
results = fillLimitOrder(data.limitOrders[orderIndices[orderType]]);
}
break;
case OrderType.Otc:
{
results = fillOtcOrder(data.otcOrders[orderIndices[orderType]]);
}
break;
case OrderType.Rfq:
{
results = fillRfqOrder(data.rfqOrders[orderIndices[orderType]]);
@@ -448,7 +486,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
}
describe('sell quotes', () => {
it('can fully sell to a single bridge order with -1 fillAmount', async () => {
it.only('can fully sell to a single bridge order with -1 fillAmount', async () => {
const bridgeOrders = [createBridgeOrder()];
const data = createTransformData({
bridgeOrders,
@@ -625,6 +663,24 @@ blockchainTests.resets('FillQuoteTransformer', env => {
return assertFinalBalancesAsync(qfr);
});
it('can fully sell to a single OTC order', async () => {
const otcOrders = [createOtcOrder()];
const data = createTransformData({
otcOrders: otcOrders.map(o => ({
order: o,
maxTakerTokenFillAmount: MAX_UINT256,
signature: createOrderSignature(),
})),
fillAmount: BigNumber.sum(...otcOrders.map(o => o.takerAmount)),
fillSequence: otcOrders.map(() => OrderType.Rfq),
});
const qfr = getExpectedQuoteFillResults(data, createSimulationState());
await executeTransformAsync({
data,
takerTokenBalance: qfr.takerTokensSpent,
});
return assertFinalBalancesAsync(qfr);
});
it('can fully sell to a single RFQ order', async () => {
const rfqOrders = [createRfqOrder()];
const data = createTransformData({
@@ -1118,6 +1174,30 @@ blockchainTests.resets('FillQuoteTransformer', env => {
return assertFinalBalancesAsync(qfr);
});
it('can fully buy to a single OTC order', async () => {
const otcOrders = [createOtcOrder()];
const totalTakerTokens = BigNumber.sum(...otcOrders.map(o => o.takerAmount));
const data = createTransformData({
side: Side.Buy,
otcOrders: otcOrders.map(o => ({
order: o,
maxTakerTokenFillAmount: MAX_UINT256,
signature: createOrderSignature(),
})),
fillAmount: BigNumber.sum(...otcOrders.map(o => o.makerAmount)),
fillSequence: otcOrders.map(() => OrderType.Rfq),
});
const qfr = getExpectedQuoteFillResults(
data,
createSimulationState({ takerTokenBalance: totalTakerTokens }),
);
await executeTransformAsync({
data,
takerTokenBalance: qfr.takerTokensSpent,
});
return assertFinalBalancesAsync(qfr);
});
it('can fully buy to a single RFQ order', async () => {
const rfqOrders = [createRfqOrder()];
const totalTakerTokens = BigNumber.sum(...rfqOrders.map(o => o.takerAmount));

View File

@@ -122,7 +122,6 @@ export * from '../test/generated-wrappers/mixin_mooniswap';
export * from '../test/generated-wrappers/mixin_nerve';
export * from '../test/generated-wrappers/mixin_platypus';
export * from '../test/generated-wrappers/mixin_shell';
export * from '../test/generated-wrappers/mixin_synthetix';
export * from '../test/generated-wrappers/mixin_uniswap';
export * from '../test/generated-wrappers/mixin_uniswap_v2';
export * from '../test/generated-wrappers/mixin_uniswap_v3';

View File

@@ -161,7 +161,6 @@
"test/generated-artifacts/MixinNerve.json",
"test/generated-artifacts/MixinPlatypus.json",
"test/generated-artifacts/MixinShell.json",
"test/generated-artifacts/MixinSynthetix.json",
"test/generated-artifacts/MixinUniswap.json",
"test/generated-artifacts/MixinUniswapV2.json",
"test/generated-artifacts/MixinUniswapV3.json",

View File

@@ -52,7 +52,7 @@
},
"config": {
"contractsPackages": "@0x/contracts-erc20 @0x/contracts-test-utils @0x/contracts-utils @0x/contracts-zero-ex @0x/contracts-treasury",
"nonContractPackages": "@0x/contract-wrappers @0x/contract-addresses @0x/contract-artifacts @0x/contract-wrappers-test",
"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",
@@ -75,6 +75,7 @@
"wsrun": "^5.2.4"
},
"resolutions": {
"merkle-patricia-tree": "3.0.0",
"**/bignumber.js": "^9.0.2"
}
}

View File

@@ -1,88 +1,12 @@
[
{
"version": "16.66.4",
"changes": [
{
"note": "Offboard Cream",
"pr": 546
},
{
"note": "Change WooFi gas estimates",
"pr": 551
}
],
"timestamp": 1661145612
},
{
"timestamp": 1660093941,
"version": "16.66.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "16.66.2",
"changes": [
{
"note": "Upgrade dependency",
"pr": 543
}
],
"timestamp": 1660073235
},
{
"version": "16.66.1",
"changes": [
{
"note": "Upgrade dependency",
"pr": 538
}
],
"timestamp": 1659926840
},
{
"version": "16.66.0",
"changes": [
{
"note": "Add WOOFi support",
"pr": 513
}
],
"timestamp": 1659750766
},
{
"version": "16.65.0",
"changes": [
{
"note": "Use 0x gas api instead of eth gas station api",
"pr": 532
}
],
"timestamp": 1659391840
},
{
"version": "16.64.0",
"changes": [
{
"note": "Refactor `TokenAdjacency` and `TokenAdjacencyBuilder`",
"pr": 517
},
{
"note": "Add Synthetix support`",
"pr": 518
},
{
"note": "Replace Beethoven X subgraph URL",
"pr": 519
},
{
"note": "Remove Mooniswap on Ethereum mainnet",
"pr": 529
"note": "Add support for OTC orders in the fillQuoteTransformer",
"pr": 516
}
],
"timestamp": 1658950329
]
},
{
"version": "16.63.1",

View File

@@ -5,38 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v16.66.4 - _August 22, 2022_
* Offboard Cream (#546)
* Change WooFi gas estimates (#551)
## v16.66.3 - _August 10, 2022_
* Dependencies updated
## v16.66.2 - _August 9, 2022_
* Upgrade dependency (#543)
## v16.66.1 - _August 8, 2022_
* Upgrade dependency (#538)
## v16.66.0 - _August 6, 2022_
* Add WOOFi support (#513)
## v16.65.0 - _August 1, 2022_
* Use 0x gas api instead of eth gas station api (#532)
## v16.64.0 - _July 27, 2022_
* Refactor `TokenAdjacency` and `TokenAdjacencyBuilder` (#517)
* Add Synthetix support` (#518)
* Replace Beethoven X subgraph URL (#519)
* Remove Mooniswap on Ethereum mainnet (#529)
## v16.63.1 - _July 12, 2022_
* Better error handling for balancer cache (#515)

View File

@@ -1,5 +1,3 @@
> :warning: **@0x/asset-swapper has been deprecated!** The `asset-swapper` code has been moved to [0x-api](https://github.com/0xProject/0x-api). Please do not open a PR with `asset-swapper` changes.
## @0x/asset-swapper
Convenience package for swapping assets represented on the Ethereum blockchain using 0x. The package helps to perform all the off-chain computations to execute a marketBuy or marketSell function execution with 0x exchange contracts, or 0x extension contracts. Given some liquidity (0x signed orders), it helps estimate the cost of buying or selling a certain asset (giving a range) and then provide varying consumable outputs to execute the buy or sell.

View File

@@ -39,13 +39,11 @@ import "./MooniswapSampler.sol";
import "./NativeOrderSampler.sol";
import "./PlatypusSampler.sol";
import "./ShellSampler.sol";
import "./SynthetixSampler.sol";
import "./TwoHopSampler.sol";
import "./UniswapSampler.sol";
import "./UniswapV2Sampler.sol";
import "./UniswapV3Sampler.sol";
import "./VelodromeSampler.sol";
import "./WooPPSampler.sol";
import "./UtilitySampler.sol";
@@ -69,13 +67,11 @@ contract ERC20BridgeSampler is
NativeOrderSampler,
PlatypusSampler,
ShellSampler,
SynthetixSampler,
TwoHopSampler,
UniswapSampler,
UniswapV2Sampler,
UniswapV3Sampler,
VelodromeSampler,
WooPPSampler,
UtilitySampler
{

View File

@@ -1,173 +0,0 @@
// 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 IReadProxyAddressResolver {
function target() external view returns (address);
}
interface IAddressResolver {
function getAddress(bytes32 name) external view returns (address);
}
interface IExchanger {
// Ethereum Mainnet
function getAmountsForAtomicExchange(
uint256 sourceAmount,
bytes32 sourceCurrencyKey,
bytes32 destinationCurrencyKey
)
external
view
returns (
uint256 amountReceived,
uint256 fee,
uint256 exchangeFeeRate
);
// Optimism
function getAmountsForExchange(
uint256 sourceAmount,
bytes32 sourceCurrencyKey,
bytes32 destinationCurrencyKey
)
external
view
returns (
uint256 amountReceived,
uint256 fee,
uint256 exchangeFeeRate
);
}
contract SynthetixSampler {
/// @dev Sample sell quotes from Synthetix Atomic Swap.
/// @param takerTokenSymbol Symbol (currency key) of the taker token (what to sell).
/// @param makerTokenSymbol Symbol (currency key) of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample (sorted in ascending order).
/// @return synthetix Synthetix address.
/// @return makerTokenAmounts Maker amounts bought at each taker token amount.
function sampleSellsFromSynthetix(
IReadProxyAddressResolver readProxy,
bytes32 takerTokenSymbol,
bytes32 makerTokenSymbol,
uint256[] memory takerTokenAmounts
) public view returns (address synthetix, uint256[] memory makerTokenAmounts) {
synthetix = getSynthetixAddress(readProxy);
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
if (numSamples == 0) {
return (synthetix, makerTokenAmounts);
}
makerTokenAmounts[0] = exchange(
readProxy,
takerTokenAmounts[0],
takerTokenSymbol,
makerTokenSymbol
);
// Synthetix atomic swap has a fixed rate. Calculate the rest based on the first value (and save gas).
for (uint256 i = 1; i < numSamples; i++) {
makerTokenAmounts[i] =
(makerTokenAmounts[0] * takerTokenAmounts[i]) /
takerTokenAmounts[0];
}
}
/// @dev Sample buy quotes from Synthetix Atomic Swap.
/// @param takerTokenSymbol Symbol (currency key) of the taker token (what to sell).
/// @param makerTokenSymbol Symbol (currency key) of the maker token (what to buy).
/// @param makerTokenAmounts Maker token buy amount for each sample (sorted in ascending order).
/// @return synthetix Synthetix address.
/// @return takerTokenAmounts Taker amounts sold at each maker token amount.
function sampleBuysFromSynthetix(
IReadProxyAddressResolver readProxy,
bytes32 takerTokenSymbol,
bytes32 makerTokenSymbol,
uint256[] memory makerTokenAmounts
) public view returns (address synthetix, uint256[] memory takerTokenAmounts) {
synthetix = getSynthetixAddress(readProxy);
// Since Synthetix atomic have a fixed rate, we can pick any reasonablely size takerTokenAmount (fixed to 1 ether here) and calculate the rest.
uint256 amountReceivedForEther = exchange(
readProxy,
1 ether,
takerTokenSymbol,
makerTokenSymbol
);
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
takerTokenAmounts[i] =
(1 ether * makerTokenAmounts[i]) /
amountReceivedForEther;
}
}
function exchange(
IReadProxyAddressResolver readProxy,
uint256 sourceAmount,
bytes32 sourceCurrencyKey,
bytes32 destinationCurrencyKey
) private view returns (uint256 amountReceived) {
IExchanger exchanger = getExchanger(readProxy);
uint256 chainId;
assembly {
chainId := chainid()
}
if (chainId == 1) {
(amountReceived, , ) = exchanger.getAmountsForAtomicExchange(
sourceAmount,
sourceCurrencyKey,
destinationCurrencyKey
);
} else {
(amountReceived, , ) = exchanger.getAmountsForExchange(
sourceAmount,
sourceCurrencyKey,
destinationCurrencyKey
);
}
}
function getSynthetixAddress(IReadProxyAddressResolver readProxy)
private
view
returns (address)
{
return IAddressResolver(readProxy.target()).getAddress("Synthetix");
}
function getExchanger(IReadProxyAddressResolver readProxy)
private
view
returns (IExchanger)
{
return
IExchanger(
IAddressResolver(readProxy.target()).getAddress("Exchanger")
);
}
}

View File

@@ -1,121 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerUtils.sol";
import "./ApproximateBuys.sol";
interface IWooPP {
/// @dev get the quote token address (immutable)
/// @return address of quote token
function quoteToken() external view returns (address);
/// @dev Query the amount for selling the base token amount.
/// @param baseToken the base token to sell
/// @param baseAmount the amount to sell
/// @return quoteAmount the swapped quote amount
function querySellBase(address baseToken, uint256 baseAmount) external view returns (uint256 quoteAmount);
/// @dev Query the amount for selling the quote token.
/// @param baseToken the base token to receive (buy)
/// @param quoteAmount the amount to sell
/// @return baseAmount the swapped base token amount
function querySellQuote(address baseToken, uint256 quoteAmount) external view returns (uint256 baseAmount);
}
contract WooPPSampler is SamplerUtils, ApproximateBuys{
function query(
uint amountIn,
address tokenIn,
address tokenOut,
address pool
) internal view returns (uint256 amountOut) {
if (amountIn == 0) {
return 0;
}
address quoteToken = IWooPP(pool).quoteToken();
if (tokenIn == quoteToken) {
amountOut = IWooPP(pool).querySellQuote(tokenOut, amountIn);
} else if (tokenOut == quoteToken) {
amountOut = IWooPP(pool).querySellBase(tokenIn, amountIn);
} else {
uint quoteAmount = IWooPP(pool).querySellBase(tokenIn, amountIn);
amountOut = IWooPP(pool).querySellQuote(tokenOut, quoteAmount);
}
}
/// @dev Sample sell quotes from WooFI.
/// @param pool Address of the pool we are sampling from
/// @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 makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromWooPP(
address pool,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
makerTokenAmounts[i] = query(takerTokenAmounts[i], takerToken, makerToken, pool);
if (makerTokenAmounts[i] == 0) {
break;
}
}
}
/// @dev Sample buy quotes from WooFI.
/// @param pool Address of the pool we are sampling from
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token sell amount for each sample (sorted in ascending order).
/// @return takerTokenAmounts Taker amounts bought at each taker token
/// amount.
function sampleBuysFromWooPP(
address pool,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = _sampleApproximateBuys(
ApproximateBuyQuoteOpts({
takerTokenData: abi.encode(pool,takerToken, makerToken),
makerTokenData: abi.encode(pool, makerToken, takerToken),
getSellQuoteCallback: _sampleSellForApproximateBuyFromWoofi
}),
makerTokenAmounts
);
}
function _sampleSellForApproximateBuyFromWoofi(
bytes memory takerTokenData,
bytes memory makerTokenData,
uint256 sellAmount
) internal view returns (uint256) {
(address _pool, address _takerToken, address _makerToken) = abi.decode(takerTokenData, (address, address, address));
(bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector(
this.sampleSellsFromWooPP.selector,
_pool,
_takerToken,
_makerToken,
_toSingleValueArray(sellAmount)
));
if(!success) {
return 0;
}
return abi.decode(resultData, (uint256[]))[0];
}
}

View File

@@ -1897,7 +1897,7 @@ ___
# Interface: SwapQuoteRequestOpts
slippagePercentage: The percentage buffer to add to account for slippage. Affects max ETH price estimates. Defaults to 0.01 (1%).
slippagePercentage: The percentage buffer to add to account for slippage. Affects max ETH price estimates. Defaults to 0.2 (20%).
gasPrice: gas price to determine protocolFee amount, default to ethGasStation fast amount

View File

@@ -1,7 +1,6 @@
{
"name": "@0x/asset-swapper",
"version": "16.66.9",
"private": true,
"version": "16.63.1",
"engines": {
"node": ">=6.12"
},
@@ -9,8 +8,8 @@
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build": "#yarn pre_build && tsc -b",
"build:ts": "#tsc -b",
"build": "yarn pre_build && tsc -b",
"build:ts": "tsc -b",
"watch": "tsc -w -p tsconfig.json",
"watch:contracts": "sol-compiler -w",
"build:ci": "yarn build",
@@ -20,11 +19,11 @@
"lint-contracts": "#solhint -c .solhint.json contracts/**/**/**/**/*.sol",
"prettier": "prettier --write '**/*.{ts,tsx,json}' --config ../../.prettierrc --ignore-path ../../.prettierignore",
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude ./test/generated-wrappers/**/* --exclude ./test/generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
"test": "#yarn run_mocha",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s clean build test",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"test:circleci": "#yarn test:coverage",
"test:circleci": "yarn test:coverage",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*_test.js' lib/test/global_hooks.js --timeout 30000 --bail --exit",
"clean": "shx rm -rf lib test_temp generated_docs test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
"diff_docs": "git diff --exit-code ./docs",
@@ -41,7 +40,7 @@
"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|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|BancorV3Sampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|IBancorV3|ICurve|IGMX|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SynthetixSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler|VelodromeSampler|WooPPSampler).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|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler|VelodromeSampler).json",
"postpublish": {
"assets": []
}
@@ -60,21 +59,21 @@
"registry": "git@github.com:0xProject/gitpkg-registry.git"
},
"dependencies": {
"@0x/assert": "^3.0.35",
"@0x/base-contract": "^7.0.0",
"@0x/contract-addresses": "^6.23.2",
"@0x/contract-wrappers": "^13.22.2",
"@0x/contracts-erc20": "^3.3.42",
"@0x/contracts-zero-ex": "^0.37.2",
"@0x/dev-utils": "^5.0.0",
"@0x/fast-abi": "^0.0.5",
"@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": "^11.16.9",
"@0x/quote-server": "^8.0.0",
"@0x/protocol-utils": "^11.15.0",
"@0x/quote-server": "^6.0.6",
"@0x/types": "^3.3.6",
"@0x/utils": "^7.0.0",
"@0x/web3-wrapper": "^8.0.0",
"@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",
@@ -85,22 +84,31 @@
"axios": "^0.21.1",
"axios-mock-adapter": "^1.19.0",
"balancer-labs-sor-v1": "npm:@balancer-labs/sor@0.3.2",
"ethereum-types": "^3.7.1",
"cream-sor": "^0.3.3",
"decimal.js": "^10.2.0",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10",
"fast-abi": "^0.0.4",
"graphql": "^15.4.0",
"graphql-request": "^3.4.0",
"heartbeats": "^5.0.1",
"lodash": "^4.17.15",
"msw": "^0.44.2"
"lodash": "^4.17.11"
},
"devDependencies": {
"@0x/abi-gen": "^5.8.1",
"@0x/contracts-gen": "^2.0.47",
"@0x/contracts-test-utils": "^5.4.33",
"@0x/sol-compiler": "^4.8.2",
"@0x/subproviders": "^7.0.0",
"@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.46",
"@0x/contracts-test-utils": "^5.4.23",
"@0x/contracts-utils": "^4.8.13",
"@0x/mesh-rpc-client": "^9.4.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",
"@types/lodash": "4.14.137",
"@0x/types": "^3.3.6",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
"chai": "^4.0.1",
@@ -108,11 +116,12 @@
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"gitpkg": "https://github.com/0xProject/gitpkg.git",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"shx": "^0.2.2",
"tslint": "^6.1.3",
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typemoq": "^2.1.0",
"typescript": "4.6.3"

View File

@@ -19,7 +19,7 @@ import {
DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID,
} from './utils/market_operation_utils/constants';
const ZERO_EX_GAS_API_URL = 'https://gas.api.0x.org/source/median';
const ETH_GAS_STATION_API_URL = 'https://ethgasstation.info/api/ethgasAPI.json';
const NULL_BYTES = '0x';
const NULL_ERC20_ASSET_DATA = '0xf47261b00000000000000000000000000000000000000000000000000000000000000000';
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
@@ -48,7 +48,7 @@ const DEFAULT_SWAP_QUOTER_OPTS: SwapQuoterOpts = {
orderRefreshIntervalMs: 10000, // 10 seconds
...DEFAULT_ORDER_PRUNER_OPTS,
samplerGasLimit: 500e6,
zeroExGasApiUrl: ZERO_EX_GAS_API_URL,
ethGasStationUrl: ETH_GAS_STATION_API_URL,
rfqt: {
integratorsWhitelist: [],
makerAssetOfferings: {},
@@ -95,10 +95,11 @@ export { DEFAULT_FEE_SCHEDULE, DEFAULT_GAS_SCHEDULE } from './utils/market_opera
export const POSITIVE_SLIPPAGE_FEE_TRANSFORMER_GAS = new BigNumber(30000);
// tslint:disable-next-line: custom-no-magic-numbers
export const KEEP_ALIVE_TTL = 5 * 60 * ONE_SECOND_MS;
export const constants = {
ZERO_EX_GAS_API_URL,
ETH_GAS_STATION_API_URL,
PROTOCOL_FEE_MULTIPLIER,
POSITIVE_SLIPPAGE_FEE_TRANSFORMER_GAS,
NULL_BYTES,

View File

@@ -157,6 +157,8 @@ export {
GetMarketOrdersRfqOpts,
LiquidityProviderFillData,
LiquidityProviderRegistry,
MarketDepth,
MarketDepthSide,
MooniswapFillData,
MultiHopFillData,
NativeRfqOrderFillData,
@@ -164,10 +166,9 @@ export {
NativeFillData,
OptimizedMarketOrder,
SourceQuoteOperation,
TokenAdjacencyGraph,
UniswapV2FillData,
} from './utils/market_operation_utils/types';
export { TokenAdjacencyGraph, TokenAdjacencyGraphBuilder } from './utils/token_adjacency_graph';
export { IdentityFillAdjustor } from './utils/market_operation_utils/identity_fill_adjustor';
export { ProtocolFeeUtils } from './utils/protocol_fee_utils';
export {

View File

@@ -32,13 +32,17 @@ import {
import { assert } from '../utils/assert';
import {
CURVE_LIQUIDITY_PROVIDER_BY_CHAIN_ID,
MOONISWAP_LIQUIDITY_PROVIDER_BY_CHAIN_ID,
NATIVE_FEE_TOKEN_BY_CHAIN_ID,
} from '../utils/market_operation_utils/constants';
import { poolEncoder } from '../utils/market_operation_utils/orders';
import {
CurveFillData,
ERC20BridgeSource,
FinalUniswapV3FillData,
LiquidityProviderFillData,
MooniswapFillData,
NativeOtcOrderFillData,
NativeRfqOrderFillData,
OptimizedMarketBridgeOrder,
OptimizedMarketOrder,
@@ -46,6 +50,7 @@ import {
} from '../utils/market_operation_utils/types';
import {
multiplexOtcOrder,
multiplexPlpEncoder,
multiplexRfqEncoder,
MultiplexSubcall,
@@ -61,6 +66,7 @@ import {
requiresTransformERC20,
} from './quote_consumer_utils';
// tslint:disable-next-line:custom-no-magic-numbers
const MAX_UINT256 = new BigNumber(2).pow(256).minus(1);
const { NULL_ADDRESS, NULL_BYTES, ZERO_AMOUNT } = constants;
@@ -303,6 +309,30 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
};
}
if (
this.chainId === ChainId.Mainnet &&
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Mooniswap])
) {
const fillData = slippedOrders[0].fillData as MooniswapFillData;
return {
calldataHexString: this._exchangeProxy
.sellToLiquidityProvider(
isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
isToETH ? ETH_TOKEN_ADDRESS : buyToken,
MOONISWAP_LIQUIDITY_PROVIDER_BY_CHAIN_ID[this.chainId],
NULL_ADDRESS,
sellAmount,
minBuyAmount,
poolEncoder.encode([fillData.poolAddress]),
)
.getABIEncodedTransactionData(),
ethAmount: isFromETH ? sellAmount : ZERO_AMOUNT,
toAddress: this._exchangeProxy.address,
allowanceTarget: this.contractAddresses.exchangeProxy,
gasOverhead: ZERO_AMOUNT,
};
}
// RFQT VIP
if (
[ChainId.Mainnet, ChainId.Polygon].includes(this.chainId) &&
@@ -312,18 +342,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
!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 fillAmountPerOrder = generateFillAmounts(sellAmount, quote);
const callData =
quote.orders.length === 1
? this._exchangeProxy
@@ -346,6 +365,46 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
};
}
// OTC orders
if (
[ChainId.Mainnet, ChainId.Ropsten].includes(this.chainId) && // @todo goerli and polygon?
quote.orders.every(o => o.type === FillQuoteTransformerOrderType.Otc) &&
!requiresTransformERC20(optsWithDefaults)
) {
const otcOrdersData = quote.orders.map(o => o.fillData as NativeOtcOrderFillData);
const fillAmountPerOrder = generateFillAmounts(sellAmount, quote);
// grab the amount to fill on each OtcOrder (if more than 1, fallback to multiplexBatchFill)
let callData;
// if we have more than one otc order we want to batch fill them,
if (quote.orders.length === 1) {
// if the otc orders takerToken is the native asset
if (isFromETH) {
callData = this._exchangeProxy
.fillOtcOrderWithEth(otcOrdersData[0].order, otcOrdersData[0].signature)
.getABIEncodedTransactionData();
}
// if the otc orders makerToken is the native asset
if (isToETH) {
callData = this._exchangeProxy
.fillOtcOrderForEth(otcOrdersData[0].order, otcOrdersData[0].signature, fillAmountPerOrder[0])
.getABIEncodedTransactionData();
} else {
// if the otc order contains 2 erc20 tokens
callData = this._exchangeProxy
.fillOtcOrder(otcOrdersData[0].order, otcOrdersData[0].signature, fillAmountPerOrder[0])
.getABIEncodedTransactionData();
}
return {
calldataHexString: callData,
ethAmount: isFromETH ? sellAmount : 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(
@@ -539,19 +598,30 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
for_loop: for (const [i, order] of quote.orders.entries()) {
switch_statement: switch (order.source) {
case ERC20BridgeSource.Native:
if (order.type !== FillQuoteTransformerOrderType.Rfq) {
if (order.type !== FillQuoteTransformerOrderType.Rfq && order.type !== FillQuoteTransformerOrderType.Otc) {
// Should never happen because we check `isMultiplexBatchFillCompatible`
// before calling this function.
throw new Error('Multiplex batch fill only supported for RFQ native orders');
throw new Error('Multiplex batch fill only supported for RFQ native orders and OTC Orders');
}
if (order.type !== FillQuoteTransformerOrderType.Otc) {
subcalls.push({
id: MultiplexSubcall.Rfq,
sellAmount: order.takerAmount,
data: multiplexRfqEncoder.encode({
order: order.fillData.order,
signature: order.fillData.signature,
}),
});
} else {
subcalls.push({
id: MultiplexSubcall.Otc,
sellAmount: order.takerAmount,
data: multiplexOtcOrder.encode({
order: order.fillData.order,
signature: order.fillData.signature,
}),
});
}
subcalls.push({
id: MultiplexSubcall.Rfq,
sellAmount: order.takerAmount,
data: multiplexRfqEncoder.encode({
order: order.fillData.order,
signature: order.fillData.signature,
}),
});
break switch_statement;
case ERC20BridgeSource.UniswapV2:
case ERC20BridgeSource.SushiSwap:
@@ -702,6 +772,17 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
}
}
function generateFillAmounts(sellAmount: BigNumber, quote: MarketBuySwapQuote | MarketSellSwapQuote): BigNumber[] {
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;
}
function slipNonNativeOrders(quote: MarketSellSwapQuote | MarketBuySwapQuote): OptimizedMarketOrder[] {
const slippage = getMaxQuoteSlippageRate(quote);
if (slippage === 0) {

View File

@@ -1,4 +1,4 @@
import { RfqOrder, SIGNATURE_ABI } from '@0x/protocol-utils';
import { OtcOrder, RfqOrder, SIGNATURE_ABI } from '@0x/protocol-utils';
import { AbiEncoder } from '@0x/utils';
export enum MultiplexSubcall {
@@ -26,6 +26,10 @@ export const multiplexRfqEncoder = AbiEncoder.create([
{ name: 'order', type: 'tuple', components: RfqOrder.STRUCT_ABI },
{ name: 'signature', type: 'tuple', components: SIGNATURE_ABI },
]);
export const multiplexOtcOrder = AbiEncoder.create([
{ name: 'order', type: 'tuple', components: OtcOrder.STRUCT_ABI },
{ name: 'signature', type: 'tuple', components: SIGNATURE_ABI },
]);
export const multiplexUniswapEncoder = AbiEncoder.create([
{ name: 'tokens', type: 'address[]' },
{ name: 'isSushi', type: 'bool' },

View File

@@ -113,11 +113,15 @@ function isOptimizedRfqOrder(x: OptimizedMarketOrder): x is OptimizedMarketOrder
*/
export function getFQTTransformerDataFromOptimizedOrders(
orders: OptimizedMarketOrder[],
): Pick<FillQuoteTransformerData, 'bridgeOrders' | 'limitOrders' | 'rfqOrders' | 'fillSequence'> {
const fqtData: Pick<FillQuoteTransformerData, 'bridgeOrders' | 'limitOrders' | 'rfqOrders' | 'fillSequence'> = {
): Pick<FillQuoteTransformerData, 'bridgeOrders' | 'limitOrders' | 'rfqOrders' | 'otcOrders' | 'fillSequence'> {
const fqtData: Pick<
FillQuoteTransformerData,
'bridgeOrders' | 'limitOrders' | 'rfqOrders' | 'otcOrders' | 'fillSequence'
> = {
bridgeOrders: [],
limitOrders: [],
rfqOrders: [],
otcOrders: [],
fillSequence: [],
};

View File

@@ -1,9 +1,9 @@
import { ChainId, getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
import { FastABI } from '@0x/fast-abi';
import { FillQuoteTransformerOrderType, LimitOrder } from '@0x/protocol-utils';
import { BigNumber, providerUtils } from '@0x/utils';
import Axios, { AxiosInstance } from 'axios';
import { BlockParamLiteral, MethodAbi, SupportedProvider, ZeroExProvider } from 'ethereum-types';
import { FastABI } from 'fast-abi';
import { Agent as HttpAgent } from 'http';
import { Agent as HttpsAgent } from 'https';
import * as _ from 'lodash';
@@ -36,6 +36,9 @@ import {
FillData,
GasSchedule,
GetMarketOrdersOpts,
MarketDepth,
MarketDepthSide,
MarketSideLiquidity,
OptimizedMarketOrder,
OptimizerResultWithReport,
} from './utils/market_operation_utils/types';
@@ -109,7 +112,7 @@ export class SwapQuoter {
};
this._protocolFeeUtils = ProtocolFeeUtils.getInstance(
constants.PROTOCOL_FEE_UTILS_POLLING_INTERVAL_IN_MS,
options.zeroExGasApiUrl,
options.ethGasStationUrl,
);
// Allow the sampler bytecode to be overwritten using geths override functionality
const samplerBytecode = _.get(artifacts.ERC20BridgeSampler, 'compilerOutput.evm.deployedBytecode.object');
@@ -144,7 +147,7 @@ export class SwapQuoter {
this.chainId,
samplerContract,
samplerOverrides,
undefined, // pools caches for balancer
undefined, // pools caches for balancer and cream
tokenAdjacencyGraph,
liquidityProviderRegistry,
this.chainId === ChainId.Mainnet // Enable Bancor only on Mainnet
@@ -225,6 +228,67 @@ export class SwapQuoter {
return batchSwapQuotes.filter(x => x !== undefined) as MarketBuySwapQuote[];
}
/**
* Returns the bids and asks liquidity for the entire market.
* For certain sources (like AMM's) it is recommended to provide a practical maximum takerAssetAmount.
* @param makerTokenAddress The address of the maker asset
* @param takerTokenAddress The address of the taker asset
* @param takerAssetAmount The amount to sell and buy for the bids and asks.
*
* @return An object that conforms to MarketDepth that contains all of the samples and liquidity
* information for the source.
*/
public async getBidAskLiquidityForMakerTakerAssetPairAsync(
makerToken: string,
takerToken: string,
takerAssetAmount: BigNumber,
options: Partial<SwapQuoteRequestOpts> = {},
): Promise<MarketDepth> {
assert.isString('makerToken', makerToken);
assert.isString('takerToken', takerToken);
const sourceFilters = new SourceFilters([], options.excludedSources, options.includedSources);
let [sellOrders, buyOrders] = !sourceFilters.isAllowed(ERC20BridgeSource.Native)
? [[], []]
: await Promise.all([
this.orderbook.getOrdersAsync(makerToken, takerToken),
this.orderbook.getOrdersAsync(takerToken, makerToken),
]);
if (!sellOrders || sellOrders.length === 0) {
sellOrders = [createDummyOrder(makerToken, takerToken)];
}
if (!buyOrders || buyOrders.length === 0) {
buyOrders = [createDummyOrder(takerToken, makerToken)];
}
const getMarketDepthSide = (marketSideLiquidity: MarketSideLiquidity): MarketDepthSide => {
const { dexQuotes, nativeOrders } = marketSideLiquidity.quotes;
const { side } = marketSideLiquidity;
return [
...dexQuotes,
nativeOrders.map(o => {
return {
input: side === MarketOperation.Sell ? o.fillableTakerAmount : o.fillableMakerAmount,
output: side === MarketOperation.Sell ? o.fillableMakerAmount : o.fillableTakerAmount,
fillData: o,
source: ERC20BridgeSource.Native,
};
}),
];
};
const [bids, asks] = await Promise.all([
this._marketOperationUtils.getMarketBuyLiquidityAsync(buyOrders, takerAssetAmount, options),
this._marketOperationUtils.getMarketSellLiquidityAsync(sellOrders, takerAssetAmount, options),
]);
return {
bids: getMarketDepthSide(bids),
asks: getMarketDepthSide(asks),
makerTokenDecimals: asks.makerTokenDecimals,
takerTokenDecimals: asks.takerTokenDecimals,
};
}
/**
* Returns the recommended gas price for a fast transaction
*/

View File

@@ -17,13 +17,11 @@ import {
GetMarketOrdersOpts,
LiquidityProviderRegistry,
OptimizedMarketOrder,
TokenAdjacencyGraph,
} from './utils/market_operation_utils/types';
export { SamplerMetrics } from './utils/market_operation_utils/types';
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from './utils/quote_report_generator';
import { MetricsProxy } from './utils/quote_requestor';
import { TokenAdjacencyGraph } from './utils/token_adjacency_graph';
export { SamplerMetrics } from './utils/market_operation_utils/types';
export type Address = string;
/**
* expiryBufferMs: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m).
@@ -337,7 +335,7 @@ export interface SwapQuoterOpts extends OrderPrunerOpts {
contractAddresses?: AssetSwapperContractAddresses;
samplerGasLimit?: number;
multiBridgeAddress?: string;
zeroExGasApiUrl?: string;
ethGasStationUrl?: string;
rfqt?: SwapQuoterRfqOpts;
samplerOverrides?: SamplerOverrides;
tokenAdjacencyGraph?: TokenAdjacencyGraph;

View File

@@ -104,9 +104,11 @@ function parseIndicativeQuoteResponseFromAltMM(
takerAmount,
// HACK: alt implementation does not return an expiration with indicative quotes
// return now + { IMPUTED EXPIRY SECONDS } to have it included after order checks
expiry: new BigNumber(Date.now() / 1000)
.integerValue(BigNumber.ROUND_DOWN)
.plus(constants.ALT_MM_IMPUTED_INDICATIVE_EXPIRY_SECONDS),
expiry:
// tslint:disable-next-line:custom-no-magic-numbers
new BigNumber(Date.now() / 1000)
.integerValue(BigNumber.ROUND_DOWN)
.plus(constants.ALT_MM_IMPUTED_INDICATIVE_EXPIRY_SECONDS),
};
}
@@ -241,6 +243,7 @@ export async function returnQuoteFromAltMMAsync<ResponseT>(
// empty response will get filtered out in validation
const emptyResponse = {};
// tslint:disable-next-line:custom-no-magic-numbers
if (response.status !== SUCCESS_CODE) {
const rejectedRequestInfo = {
status: response.status,

View File

@@ -40,6 +40,7 @@ interface Cache {
[key: string]: AaveReserve[];
}
// tslint:disable-next-line:custom-no-magic-numbers
const RESERVES_REFRESH_INTERVAL_MS = 30 * constants.ONE_MINUTE_MS;
/**

View File

@@ -33,8 +33,8 @@ import {
MSTABLE_POOLS_BY_CHAIN_ID,
NERVE_BSC_INFOS,
NULL_ADDRESS,
PANCAKESWAPV2_ROUTER_BY_CHAIN_ID,
PANCAKESWAP_ROUTER_BY_CHAIN_ID,
PANCAKESWAPV2_ROUTER_BY_CHAIN_ID,
PANGOLIN_ROUTER_BY_CHAIN_ID,
PLATYPUS_AVALANCHE_INFOS,
QUICKSWAP_ROUTER_BY_CHAIN_ID,

View File

@@ -19,6 +19,7 @@ interface Cache {
[key: string]: CToken;
}
// tslint:disable-next-line:custom-no-magic-numbers
const CTOKEN_REFRESH_INTERVAL_MS = 30 * constants.ONE_MINUTE_MS;
/**

View File

@@ -1,9 +1,9 @@
import { ChainId, getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
import { FillQuoteTransformerOrderType } from '@0x/protocol-utils';
import { BigNumber } from '@0x/utils';
import { formatBytes32String, parseBytes32String } from '@ethersproject/strings';
import { formatBytes32String } from '@ethersproject/strings';
import { TokenAdjacencyGraph, TokenAdjacencyGraphBuilder } from '../token_adjacency_graph';
import { TokenAdjacencyGraphBuilder } from '../token_adjacency_graph_builder';
import { IdentityFillAdjustor } from './identity_fill_adjustor';
import { SourceFilters } from './source_filters';
@@ -32,13 +32,12 @@ import {
MultiHopFillData,
PlatypusInfo,
PsmInfo,
SynthetixFillData,
TokenAdjacencyGraph,
UniswapV2FillData,
UniswapV3FillData,
WOOFiFillData,
} from './types';
// tslint:disable: no-bitwise
// tslint:disable: custom-no-magic-numbers no-bitwise
export const ERC20_PROXY_ID = '0xf47261b0';
export const WALLET_SIGNATURE = '0x04';
@@ -61,7 +60,6 @@ function valueByChainId<T>(rest: Partial<{ [key in ChainId]: T }>, defaultValue:
[ChainId.Mainnet]: defaultValue,
[ChainId.Ropsten]: defaultValue,
[ChainId.Rinkeby]: defaultValue,
[ChainId.Goerli]: defaultValue,
[ChainId.Kovan]: defaultValue,
[ChainId.Ganache]: defaultValue,
[ChainId.BSC]: defaultValue,
@@ -71,8 +69,6 @@ function valueByChainId<T>(rest: Partial<{ [key in ChainId]: T }>, defaultValue:
[ChainId.Fantom]: defaultValue,
[ChainId.Celo]: defaultValue,
[ChainId.Optimism]: defaultValue,
[ChainId.ArbitrumRinkeby]: defaultValue,
[ChainId.Arbitrum]: defaultValue,
...(rest || {}),
};
}
@@ -92,11 +88,13 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Bancor,
ERC20BridgeSource.BancorV3,
ERC20BridgeSource.MStable,
ERC20BridgeSource.Mooniswap,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Shell,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Dodo,
ERC20BridgeSource.DodoV2,
ERC20BridgeSource.Cream,
ERC20BridgeSource.LiquidityProvider,
ERC20BridgeSource.CryptoCom,
ERC20BridgeSource.Lido,
@@ -109,7 +107,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.ShibaSwap,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.Synthetix,
// TODO: enable after FQT has been redeployed on Ethereum mainnet
// ERC20BridgeSource.AaveV2,
// ERC20BridgeSource.Compound,
@@ -121,17 +118,10 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.UniswapV2,
ERC20BridgeSource.UniswapV3,
ERC20BridgeSource.Curve,
ERC20BridgeSource.Mooniswap,
]),
[ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.Kovan]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.Goerli]: new SourceFilters([
ERC20BridgeSource.Native,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.UniswapV2,
ERC20BridgeSource.UniswapV3,
]),
[ChainId.PolygonMumbai]: new SourceFilters([ERC20BridgeSource.Native, ERC20BridgeSource.UniswapV3]),
[ChainId.Ganache]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.BSC]: new SourceFilters([
ERC20BridgeSource.BakerySwap,
@@ -156,7 +146,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.BiSwap,
ERC20BridgeSource.MDex,
ERC20BridgeSource.KnightSwap,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Polygon]: new SourceFilters([
ERC20BridgeSource.SushiSwap,
@@ -179,7 +168,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.UniswapV3,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.MeshSwap,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Avalanche]: new SourceFilters([
ERC20BridgeSource.MultiHop,
@@ -193,7 +181,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Synapse,
ERC20BridgeSource.GMX,
ERC20BridgeSource.Platypus,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Fantom]: new SourceFilters([
ERC20BridgeSource.MultiHop,
@@ -207,7 +194,6 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.Yoshi,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Celo]: new SourceFilters([
ERC20BridgeSource.UbeSwap,
@@ -222,9 +208,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Velodrome,
ERC20BridgeSource.Synthetix,
]),
[ChainId.ArbitrumRinkeby]: new SourceFilters([ERC20BridgeSource.Native, ERC20BridgeSource.UniswapV3]),
},
new SourceFilters([]),
);
@@ -244,11 +228,13 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
// ERC20BridgeSource.Bancor, // FIXME: Bancor Buys not implemented in Sampler
ERC20BridgeSource.BancorV3,
ERC20BridgeSource.MStable,
ERC20BridgeSource.Mooniswap,
ERC20BridgeSource.Shell,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Dodo,
ERC20BridgeSource.DodoV2,
ERC20BridgeSource.Cream,
ERC20BridgeSource.Lido,
ERC20BridgeSource.LiquidityProvider,
ERC20BridgeSource.CryptoCom,
@@ -261,7 +247,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.ShibaSwap,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.Synthetix,
// TODO: enable after FQT has been redeployed on Ethereum mainnet
// ERC20BridgeSource.AaveV2,
// ERC20BridgeSource.Compound,
@@ -273,15 +258,8 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.UniswapV2,
ERC20BridgeSource.UniswapV3,
ERC20BridgeSource.Curve,
ERC20BridgeSource.Mooniswap,
]),
[ChainId.Goerli]: new SourceFilters([
ERC20BridgeSource.Native,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Uniswap,
ERC20BridgeSource.UniswapV2,
ERC20BridgeSource.UniswapV3,
]),
[ChainId.PolygonMumbai]: new SourceFilters([ERC20BridgeSource.Native, ERC20BridgeSource.UniswapV3]),
[ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.Kovan]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.Ganache]: new SourceFilters([ERC20BridgeSource.Native]),
@@ -308,7 +286,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.BiSwap,
ERC20BridgeSource.MDex,
ERC20BridgeSource.KnightSwap,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Polygon]: new SourceFilters([
ERC20BridgeSource.SushiSwap,
@@ -331,7 +308,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.UniswapV3,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.MeshSwap,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Avalanche]: new SourceFilters([
ERC20BridgeSource.MultiHop,
@@ -345,7 +321,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Synapse,
ERC20BridgeSource.GMX,
ERC20BridgeSource.Platypus,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Fantom]: new SourceFilters([
ERC20BridgeSource.MultiHop,
@@ -359,7 +334,6 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.Yoshi,
ERC20BridgeSource.WOOFi,
]),
[ChainId.Celo]: new SourceFilters([
ERC20BridgeSource.UbeSwap,
@@ -374,9 +348,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Velodrome,
ERC20BridgeSource.Synthetix,
]),
[ChainId.ArbitrumRinkeby]: new SourceFilters([ERC20BridgeSource.Native, ERC20BridgeSource.UniswapV3]),
},
new SourceFilters([]),
);
@@ -394,14 +366,11 @@ export const FEE_QUOTE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>
[ChainId.Mainnet]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.UniswapV3],
[ChainId.BSC]: [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.SushiSwap],
[ChainId.Ropsten]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap],
[ChainId.Goerli]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap],
[ChainId.PolygonMumbai]: [ERC20BridgeSource.UniswapV3],
[ChainId.Polygon]: [ERC20BridgeSource.QuickSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.UniswapV3],
[ChainId.Avalanche]: [ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap],
[ChainId.Fantom]: [ERC20BridgeSource.SpiritSwap, ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SushiSwap],
[ChainId.Celo]: [ERC20BridgeSource.UbeSwap, ERC20BridgeSource.SushiSwap],
[ChainId.Optimism]: [ERC20BridgeSource.UniswapV3],
[ChainId.ArbitrumRinkeby]: [ERC20BridgeSource.UniswapV3],
},
[],
);
@@ -418,6 +387,23 @@ export const SOURCE_FLAGS: { [key in ERC20BridgeSource]: bigint } & {
})),
);
const MIRROR_WRAPPED_TOKENS = {
mAAPL: '0xd36932143f6ebdedd872d5fb0651f4b72fd15a84',
mSLV: '0x9d1555d8cb3c846bb4f7d5b1b1080872c3166676',
mIAU: '0x1d350417d9787e000cc1b95d70e9536dcd91f373',
mAMZN: '0x0cae9e4d663793c2a2a0b211c1cf4bbca2b9caa7',
mGOOGL: '0x4b70ccd1cf9905be1faed025eadbd3ab124efe9a',
mTSLA: '0x21ca39943e91d704678f5d00b6616650f066fd63',
mQQQ: '0x13b02c8de71680e71f0820c996e4be43c2f57d15',
mTWTR: '0xedb0414627e6f1e3f082de65cd4f9c693d78cca9',
mMSFT: '0x41bbedd7286daab5910a1f15d12cbda839852bd7',
mNFLX: '0xc8d674114bac90148d11d3c1d33c61835a0f9dcd',
mBABA: '0x676ce85f66adb8d7b8323aeefe17087a3b8cb363',
mUSO: '0x31c63146a635eb7465e5853020b39713ac356991',
mVIXY: '0xf72fcd9dcf0190923fadd44811e240ef4533fc86',
mLUNA: '0xd2877702675e6ceb975b4a1dff9fb7baf4c91ea9',
};
// Mainnet tokens
// Not an exhaustive list, just enough so we don't repeat ourselves
export const MAINNET_TOKENS = {
@@ -456,11 +442,6 @@ export const MAINNET_TOKENS = {
EURS: '0xdb25f211ab05b1c97d595516f45794528a807ad8',
sEUR: '0xd71ecff9342a5ced620049e616c5035f1db98620',
sETH: '0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb',
sJPY: '0xf6b1c627e95bfc3c1b4c9b825a032ff0fbf3e07d',
sGBP: '0x97fe22e7341a0cd8db6f6c021a24dc8f4dad855f',
sAUD: '0xf48e200eaf9906362bb1442fca31e0835773b8b4',
sKRW: '0x269895a3df4d73b077fc823dd6da1b95f72aaf9b',
sCHF: '0x0f83287ff768d1c1e17a42f44d644d7f22e8ee1d',
stETH: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84',
wstETH: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0',
LINK: '0x514910771af9ca656af840dff83e8264ecf986ca',
@@ -481,7 +462,10 @@ export const MAINNET_TOKENS = {
vETH: '0x898bad2774eb97cf6b94605677f43b41871410b1',
alETH: '0x0100546f2cd4c9d97f798ffc9755e47865ff7ee6',
HT: '0x6f259637dcD74C767781E37Bc6133cd6A68aa161',
// Mirror Protocol
UST: '0xa47c8bf37f92abed4a126bda807a7b7498661acd',
MIR: '0x09a3ecafa817268f77be1283176b946c4ff2e608',
...MIRROR_WRAPPED_TOKENS,
// StableSwap "open pools" (crv.finance)
STABLEx: '0xcd91538b91b4ba7797d39a2f66e63810b50a33d0',
alUSD: '0xbc6da0fe9ad5f3b0d58160288917aa56653660e9',
@@ -534,7 +518,6 @@ export const BSC_TOKENS = {
pBTC: '0xed28a457a5a76596ac48d87c0f577020f6ea1c4c',
nUSD: '0x23b891e5c62e0955ae2bd185990103928ab817b3',
BSW: '0x965F527D9159dCe6288a2219DB51fc6Eef120dD1',
WOO: '0x4691937a7508860f876c9c0a2a617e7d9e945d4b',
};
export const POLYGON_TOKENS = {
@@ -554,7 +537,6 @@ export const POLYGON_TOKENS = {
WEXPOLY: '0x4c4bf319237d98a30a929a96112effa8da3510eb',
nUSD: '0xb6c473756050de474286bed418b77aeac39b02af',
ANY: '0x6aB6d61428fde76768D7b45D8BFeec19c6eF91A8',
WOO: '0x1b815d120b3ef02039ee11dc2d33de7aa4a8c603',
};
export const AVALANCHE_TOKENS = {
@@ -581,7 +563,6 @@ export const AVALANCHE_TOKENS = {
UST: '0xb599c3590f42f8f995ecfa0f85d2980b76862fc1',
FRAX: '0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64',
YUSD: '0x111111111111ed1d73f860f57b2798b683f2d325',
WOO: '0xabc9547b534519ff73921b1fba6e672b5f58d083',
};
export const CELO_TOKENS = {
@@ -641,7 +622,10 @@ export const FANTOM_TOKENS = {
gWBTC: '0x38aca5484b8603373acc6961ecd57a6a594510a3',
gCRV: '0x690754a168b022331caa2467207c61919b3f8a98',
gMIM: '0xc664fc7b8487a3e10824cda768c1d239f2403bbe',
WOO: '0x6626c47c00f1d87902fc13eecfac3ed06d5e8d8a',
};
export const GEIST_FANTOM_POOLS = {
lendingPool: '0x9fad24f572045c7869117160a571b2e50b10d068',
};
export const OPTIMISM_TOKENS = {
@@ -652,21 +636,6 @@ export const OPTIMISM_TOKENS = {
WBTC: '0x68f180fcce6836688e9084f035309e29bf0a2095',
nETH: '0x809dc529f07651bd43a172e8db6f4a7a0d771036',
sWETH: '0x121ab82b49b2bc4c7901ca46b8277962b4350204',
// Synthetix synths:
sAAVE: '0x00b8d5a5e1ac97cb4341c4bc4367443c8776e8d9',
sAVAX: '0xb2b42b231c68cbb0b4bf2ffebf57782fd97d3da4',
sBTC: '0x298b9b95708152ff6968aafd889c6586e9169f1d',
sETH: '0xe405de8f52ba7559f9df3c368500b6e6ae6cee49',
sEUR: '0xfbc4198702e81ae77c06d58f81b629bdf36f0a71',
sLINK: '0xc5db22719a06418028a40a9b5e9a7c02959d0d08',
sMATIC: '0x81ddfac111913d3d5218dea999216323b7cd6356',
sSOL: '0x8b2f7ae8ca8ee8428b6d76de88326bb413db2766',
sUNI: '0xf5a6115aa582fd1beea22bc93b7dc7a785f60d03',
sUSD: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9',
};
export const GEIST_FANTOM_POOLS = {
lendingPool: '0x9fad24f572045c7869117160a571b2e50b10d068',
};
export const CURVE_POOLS = {
@@ -718,6 +687,8 @@ export const CURVE_POOLS = {
eurt: '0xfd5db7463a3ab53fd211b4af195c5bccc1a03890',
ethcrv: '0x8301ae4fc9c624d1d396cbdaa1ed877821d7c511',
ethcvx: '0xb576491f1e6e5e62f1d8f26062ee822b40b0e0d4',
mimust: '0x55a8a39bc9694714e2874c1ce77aa1e599461e18',
usttri_wormhole: '0xceaf7747579696a2f0bb206a14210e3c9e6fb269',
fei_tri: '0x06cb22615ba53e60d67bf6c341a0fd5e718e1655',
rai_tri: '0x618788357d0ebd8a37e763adab3bc575d54c2c7d',
DOLA_tri: '0xaa5a67c256e27a5d80712c51971408db3370927d',
@@ -858,39 +829,6 @@ export const PLATYPUS_AVALANCHE_POOLS = {
sAVAX: '0x4658ea7e9960d6158a261104aaa160cc953bb6ba',
};
export const WOOFI_POOL_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.BSC]: '0xbf365ce9cfcb2d5855521985e351ba3bcf77fd3f',
[ChainId.Fantom]: '0x9503e7517d3c5bc4f9e4a1c6ae4f8b33ac2546f2',
[ChainId.Avalanche]: '0x1df3009c57a8b143c6246149f00b090bce3b8f88',
[ChainId.Polygon]: '0x7400b665c8f4f3a951a99f1ee9872efb8778723d',
},
NULL_ADDRESS,
);
export const WOOFI_SUPPORTED_TOKENS = new Set([
BSC_TOKENS.USDT,
BSC_TOKENS.WBNB,
BSC_TOKENS.WOO,
BSC_TOKENS.WETH,
BSC_TOKENS.BTCB,
AVALANCHE_TOKENS.nUSDC,
AVALANCHE_TOKENS.WAVAX,
AVALANCHE_TOKENS.WBTC,
AVALANCHE_TOKENS.WETH,
AVALANCHE_TOKENS.WOO,
FANTOM_TOKENS.USDC,
FANTOM_TOKENS.WFTM,
FANTOM_TOKENS.WETH,
FANTOM_TOKENS.WBTC,
FANTOM_TOKENS.WOO,
POLYGON_TOKENS.USDC,
POLYGON_TOKENS.WMATIC,
POLYGON_TOKENS.WBTC,
POLYGON_TOKENS.WETH,
POLYGON_TOKENS.WOO,
]);
export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
{
[ChainId.Mainnet]: [
@@ -914,20 +852,6 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
'0xad6d458402f60fd3bd25163575031acdce07538d', // DAI
'0x07865c6e87b9f70255377e024ace6630c1eaa37f', // USDC
],
[ChainId.Goerli]: [
getContractAddressesForChainOrThrow(ChainId.Goerli).etherToken,
'0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844', // DAI
'0x07865c6E87B9F70255377e024ace6630C1Eaa37F', // USDC
],
[ChainId.ArbitrumRinkeby]: [
getContractAddressesForChainOrThrow(ChainId.ArbitrumRinkeby).etherToken,
'0x237b3B5238D2022aA80cAd1f67dAE53f353F74bF', // USDT
'0xF61Cffd6071a8DB7cD5E8DF1D3A5450D9903cF1c', // USDC
],
[ChainId.PolygonMumbai]: [
getContractAddressesForChainOrThrow(ChainId.PolygonMumbai).etherToken,
'0xe6b8a5CF854791412c1f6EFC7CAf629f5Df1c747', // USDC
],
[ChainId.Polygon]: [
POLYGON_TOKENS.WMATIC,
POLYGON_TOKENS.WETH,
@@ -979,72 +903,65 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
// attaching to a default intermediary token (stables or ETH etc) can have a large impact
export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdjacencyGraph>(
{
[ChainId.Mainnet]: new TokenAdjacencyGraphBuilder(DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Mainnet])
[ChainId.Mainnet]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Mainnet],
})
.tap(builder => {
// Mirror Protocol
builder.add(MAINNET_TOKENS.MIR, MAINNET_TOKENS.UST);
// Convex and Curve
builder.addBidirectional(MAINNET_TOKENS.cvxCRV, MAINNET_TOKENS.CRV);
builder.add(MAINNET_TOKENS.cvxCRV, MAINNET_TOKENS.CRV).add(MAINNET_TOKENS.CRV, MAINNET_TOKENS.cvxCRV);
// Convex and FXS
builder.addBidirectional(MAINNET_TOKENS.cvxFXS, MAINNET_TOKENS.FXS);
builder.add(MAINNET_TOKENS.cvxFXS, MAINNET_TOKENS.FXS).add(MAINNET_TOKENS.FXS, MAINNET_TOKENS.cvxFXS);
// FEI TRIBE liquid in UniV2
builder.addBidirectional(MAINNET_TOKENS.FEI, MAINNET_TOKENS.TRIBE);
builder.add(MAINNET_TOKENS.FEI, MAINNET_TOKENS.TRIBE).add(MAINNET_TOKENS.TRIBE, MAINNET_TOKENS.FEI);
// FRAX ecosystem
builder.addBidirectional(MAINNET_TOKENS.FRAX, MAINNET_TOKENS.FXS);
builder.addBidirectional(MAINNET_TOKENS.FRAX, MAINNET_TOKENS.OHM);
builder.add(MAINNET_TOKENS.FRAX, MAINNET_TOKENS.FXS).add(MAINNET_TOKENS.FXS, MAINNET_TOKENS.FRAX);
builder.add(MAINNET_TOKENS.FRAX, MAINNET_TOKENS.OHM).add(MAINNET_TOKENS.OHM, MAINNET_TOKENS.FRAX);
// REDACTED CARTEL
builder.addBidirectional(MAINNET_TOKENS.OHMV2, MAINNET_TOKENS.BTRFLY);
builder
.add(MAINNET_TOKENS.OHMV2, MAINNET_TOKENS.BTRFLY)
.add(MAINNET_TOKENS.BTRFLY, MAINNET_TOKENS.OHMV2);
// Lido
builder.addBidirectional(MAINNET_TOKENS.stETH, MAINNET_TOKENS.wstETH);
// Synthetix Atomic Swap
builder.addCompleteSubgraph([
MAINNET_TOKENS.sBTC,
MAINNET_TOKENS.sETH,
MAINNET_TOKENS.sUSD,
MAINNET_TOKENS.sEUR,
MAINNET_TOKENS.sJPY,
MAINNET_TOKENS.sGBP,
MAINNET_TOKENS.sAUD,
MAINNET_TOKENS.sKRW,
MAINNET_TOKENS.sCHF,
]);
builder
.add(MAINNET_TOKENS.stETH, MAINNET_TOKENS.wstETH)
.add(MAINNET_TOKENS.wstETH, MAINNET_TOKENS.stETH);
})
// Build
.build(),
[ChainId.BSC]: new TokenAdjacencyGraphBuilder(DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.BSC]).build(),
[ChainId.Polygon]: new TokenAdjacencyGraphBuilder(DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Polygon])
[ChainId.BSC]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.BSC],
}).build(),
[ChainId.Polygon]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Polygon],
})
.tap(builder => {
builder.addBidirectional(POLYGON_TOKENS.QUICK, POLYGON_TOKENS.ANY);
builder.add(POLYGON_TOKENS.QUICK, POLYGON_TOKENS.ANY).add(POLYGON_TOKENS.ANY, POLYGON_TOKENS.QUICK);
})
.build(),
[ChainId.Avalanche]: new TokenAdjacencyGraphBuilder(DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Avalanche])
[ChainId.Avalanche]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Avalanche],
})
.tap(builder => {
// Synapse nETH/aWETH pool
builder.addBidirectional(AVALANCHE_TOKENS.aWETH, AVALANCHE_TOKENS.nETH);
builder
.add(AVALANCHE_TOKENS.aWETH, AVALANCHE_TOKENS.nETH)
.add(AVALANCHE_TOKENS.nETH, AVALANCHE_TOKENS.aWETH);
// Trader Joe MAG/MIM pool
builder.addBidirectional(AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.MAG);
})
.build(),
[ChainId.Fantom]: new TokenAdjacencyGraphBuilder(
DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Fantom],
).build(),
[ChainId.Celo]: new TokenAdjacencyGraphBuilder(DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Celo]).build(),
[ChainId.Optimism]: new TokenAdjacencyGraphBuilder(DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Optimism])
.tap(builder => {
// Synthetix Atomic Swap
builder.addCompleteSubgraph([
OPTIMISM_TOKENS.sAAVE,
OPTIMISM_TOKENS.sAVAX,
OPTIMISM_TOKENS.sBTC,
OPTIMISM_TOKENS.sETH,
OPTIMISM_TOKENS.sEUR,
OPTIMISM_TOKENS.sLINK,
OPTIMISM_TOKENS.sMATIC,
OPTIMISM_TOKENS.sSOL,
OPTIMISM_TOKENS.sUNI,
OPTIMISM_TOKENS.sUSD,
]);
builder.add(AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.MAG).add(AVALANCHE_TOKENS.MAG, AVALANCHE_TOKENS.MIM);
})
.build(),
[ChainId.Fantom]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Fantom],
}).build(),
[ChainId.Celo]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Celo],
}).build(),
[ChainId.Optimism]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Optimism],
}).build(),
},
TokenAdjacencyGraph.getEmptyGraph(),
new TokenAdjacencyGraphBuilder({ default: [] }).build(),
);
export const NATIVE_FEE_TOKEN_BY_CHAIN_ID = valueByChainId<string>(
@@ -1053,9 +970,6 @@ export const NATIVE_FEE_TOKEN_BY_CHAIN_ID = valueByChainId<string>(
[ChainId.BSC]: getContractAddressesForChainOrThrow(ChainId.BSC).etherToken,
[ChainId.Ganache]: getContractAddressesForChainOrThrow(ChainId.Ganache).etherToken,
[ChainId.Ropsten]: getContractAddressesForChainOrThrow(ChainId.Ropsten).etherToken,
[ChainId.Goerli]: getContractAddressesForChainOrThrow(ChainId.Goerli).etherToken,
[ChainId.PolygonMumbai]: getContractAddressesForChainOrThrow(ChainId.PolygonMumbai).etherToken,
[ChainId.ArbitrumRinkeby]: getContractAddressesForChainOrThrow(ChainId.ArbitrumRinkeby).etherToken,
[ChainId.Rinkeby]: getContractAddressesForChainOrThrow(ChainId.Rinkeby).etherToken,
[ChainId.Kovan]: getContractAddressesForChainOrThrow(ChainId.Kovan).etherToken,
[ChainId.Polygon]: getContractAddressesForChainOrThrow(ChainId.Polygon).etherToken,
@@ -1389,6 +1303,16 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_uint256,
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_uint256,
},
[CURVE_POOLS.mimust]: createCurveExchangePool({
tokens: [MAINNET_TOKENS.MIM, MAINNET_TOKENS.UST],
pool: CURVE_POOLS.mimust,
gasSchedule: 105e3,
}),
[CURVE_POOLS.usttri_wormhole]: createCurveMetaTriPool({
tokens: [MAINNET_TOKENS.UST_WORMHOLE],
pool: CURVE_POOLS.usttri_wormhole,
gasSchedule: 340e3,
}),
[CURVE_POOLS.fei_tri]: createCurveMetaTriPool({
tokens: [MAINNET_TOKENS.FEI],
pool: CURVE_POOLS.fei_tri,
@@ -1909,7 +1833,6 @@ export const UNISWAPV1_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Mainnet]: '0xc0a47dfe034b400b47bdad5fecda2621de6c4d95',
[ChainId.Ropsten]: '0x9c83dce8ca20e9aaf9d3efc003b2ea62abc08351',
[ChainId.Goerli]: '0x6Ce570d02D73d4c384b46135E87f8C592A8c86dA',
},
NULL_ADDRESS,
);
@@ -1918,7 +1841,6 @@ export const UNISWAPV2_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Mainnet]: '0xf164fc0ec4e93095b804a4795bbe1e041497b92a',
[ChainId.Ropsten]: '0xf164fc0ec4e93095b804a4795bbe1e041497b92a',
[ChainId.Goerli]: '0xf164fc0ec4e93095b804a4795bbe1e041497b92a',
},
NULL_ADDRESS,
);
@@ -1928,7 +1850,6 @@ export const SUSHISWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
[ChainId.Mainnet]: '0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f',
[ChainId.BSC]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Ropsten]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Goerli]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Polygon]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Avalanche]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
[ChainId.Fantom]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
@@ -2020,6 +1941,7 @@ export const KNIGHTSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
export const MOONISWAP_REGISTRIES_BY_CHAIN_ID = valueByChainId(
{
[ChainId.Mainnet]: ['0xbaf9a5d4b0052359326a6cdab54babaa3a3a9643'],
[ChainId.BSC]: ['0xd41b24bba51fac0e4827b6f94c0d6ddeb183cd64'],
},
[] as string[],
@@ -2089,6 +2011,14 @@ export const MAKER_PSM_INFO_BY_CHAIN_ID = valueByChainId<PsmInfo>(
},
);
export const MOONISWAP_LIQUIDITY_PROVIDER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Mainnet]: '0xa2033d6ba88756ce6a87584d69dc87bda9a4f889',
[ChainId.Ropsten]: '0x87e0393aee0fb8c10b8653c6507c182264fe5a34',
},
NULL_ADDRESS,
);
export const BANCOR_REGISTRY_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Mainnet]: '0x52Ae12ABe5D8BD778BD5397F99cA900624CfADD4',
@@ -2197,6 +2127,7 @@ export const LIDO_INFO_BY_CHAIN = valueByChainId<LidoInfo>(
},
);
export const BALANCER_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer';
export const BALANCER_TOP_POOLS_FETCHED = 250;
export const BALANCER_MAX_POOLS_FETCHED = 3;
@@ -2208,6 +2139,13 @@ export const BALANCER_V2_SUBGRAPH_URL_BY_CHAIN = valueByChainId(
null,
);
export const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
{
[ChainId.Fantom]: 'https://graph-node.beets-ftm-node.com/subgraphs/name/beethovenx',
},
'https://graph-node.beets-ftm-node.com/subgraphs/name/beethovenx',
);
export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
{
[ChainId.Mainnet]: {
@@ -2218,14 +2156,6 @@ export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.Goerli]: {
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.PolygonMumbai]: {
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.Polygon]: {
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
@@ -2234,10 +2164,6 @@ export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.ArbitrumRinkeby]: {
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
},
{ quoter: NULL_ADDRESS, router: NULL_ADDRESS },
);
@@ -2415,47 +2341,6 @@ export const VELODROME_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
NULL_ADDRESS,
);
export const SYNTHETIX_READ_PROXY_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Mainnet]: '0x4e3b31eb0e5cb73641ee1e65e7dcefe520ba3ef2',
[ChainId.Optimism]: '0x1cb059b7e74fd21665968c908806143e744d5f30',
},
NULL_ADDRESS,
);
export const SYNTHETIX_CURRENCY_KEYS_BY_CHAIN_ID = valueByChainId<Map<string, string>>(
{
// There is no easy way to find out what synths are supported on mainnet.
// The below list is based on https://sips.synthetix.io/sccp/sccp-190.
[ChainId.Mainnet]: new Map([
[MAINNET_TOKENS.sAUD, 'sAUD'],
[MAINNET_TOKENS.sBTC, 'sBTC'],
[MAINNET_TOKENS.sCHF, 'sCHF'],
[MAINNET_TOKENS.sETH, 'sETH'],
[MAINNET_TOKENS.sEUR, 'sEUR'],
[MAINNET_TOKENS.sGBP, 'sGBP'],
[MAINNET_TOKENS.sJPY, 'sJPY'],
[MAINNET_TOKENS.sKRW, 'sKRW'],
[MAINNET_TOKENS.sUSD, 'sUSD'],
]),
// Supported assets can be find through SynthUtil::synthsRates.
// Low liquidity tokens can be excluded.
[ChainId.Optimism]: new Map([
[OPTIMISM_TOKENS.sAAVE, 'sAAVE'],
[OPTIMISM_TOKENS.sAVAX, 'sAVAX'],
[OPTIMISM_TOKENS.sBTC, 'sBTC'],
[OPTIMISM_TOKENS.sETH, 'sETH'],
[OPTIMISM_TOKENS.sEUR, 'sEUR'],
[OPTIMISM_TOKENS.sLINK, 'sLINK'],
[OPTIMISM_TOKENS.sMATIC, 'sMATIC'],
[OPTIMISM_TOKENS.sSOL, 'sSOL'],
[OPTIMISM_TOKENS.sUNI, 'sUNI'],
[OPTIMISM_TOKENS.sUSD, 'sUSD'],
]),
},
new Map(),
);
export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>(
{
[ChainId.Mainnet]: [
@@ -2497,6 +2382,7 @@ const uniswapV2CloneGasSchedule = (fillData?: FillData) => {
* I.e remove the overhead cost of ExchangeProxy (130k) and
* the ethereum transaction cost (21k)
*/
// tslint:disable:custom-no-magic-numbers
export const DEFAULT_GAS_SCHEDULE: Required<GasSchedule> = {
[ERC20BridgeSource.Native]: fillData => {
// TODO jacob re-order imports so there is no circular rependency with SignedNativeOrder
@@ -2533,6 +2419,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<GasSchedule> = {
[ERC20BridgeSource.BalancerV2]: (fillData?: FillData) => {
return 100e3 + ((fillData as BalancerV2BatchSwapFillData).swapSteps.length - 1) * 50e3;
},
[ERC20BridgeSource.Cream]: () => 120e3,
[ERC20BridgeSource.MStable]: () => 200e3,
[ERC20BridgeSource.MakerPsm]: (fillData?: FillData) => {
const psmFillData = fillData as MakerPsmFillData;
@@ -2637,28 +2524,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<GasSchedule> = {
return compoundFillData.takerToken === wethAddress ? 210e3 : 250e3;
}
},
[ERC20BridgeSource.Synthetix]: (fillData?: FillData) => {
const { chainId, makerTokenSymbolBytes32, takerTokenSymbolBytes32 } = fillData as SynthetixFillData;
const makerTokenSymbol = parseBytes32String(makerTokenSymbolBytes32);
const takerTokenSymbol = parseBytes32String(takerTokenSymbolBytes32);
// Gas cost widely varies by token on mainnet.
if (chainId === ChainId.Mainnet) {
if (takerTokenSymbol === 'sBTC' || makerTokenSymbol === 'sBTC') {
return 800e3;
}
if (takerTokenSymbol === 'sETH' || makerTokenSymbol === 'sETH') {
return 700e3;
}
return 580e3;
}
// Optimism
if (takerTokenSymbol === 'sUSD' || makerTokenSymbol === 'sUSD') {
return 480e3;
}
return 580e3;
},
//
// BSC
//
@@ -2669,39 +2535,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<GasSchedule> = {
[ERC20BridgeSource.CheeseSwap]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.WaultSwap]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.ACryptos]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.WOOFi]: (fillData?: FillData) => {
const woofiFillData = fillData as WOOFiFillData;
const quoteTokenAddresses = [BSC_TOKENS.USDT, AVALANCHE_TOKENS.nUSDC, FANTOM_TOKENS.USDC, POLYGON_TOKENS.USDC];
const hasQuoteToken =
quoteTokenAddresses.includes(woofiFillData.takerToken) ||
quoteTokenAddresses.includes(woofiFillData.makerToken);
if (woofiFillData.chainId === ChainId.BSC) {
if (hasQuoteToken) {
return 550e3;
} else {
return 100e4;
}
} else if (woofiFillData.chainId === ChainId.Avalanche) {
if (hasQuoteToken) {
return 300e3;
} else {
return 550e3;
}
} else if (woofiFillData.chainId === ChainId.Polygon) {
if (hasQuoteToken) {
return 500e3;
} else {
return 700e3;
}
} else {
// Fantom
if (hasQuoteToken) {
return 400e3;
} else {
return 600e3;
}
}
},
//
// Polygon
//
@@ -2752,7 +2586,10 @@ export const POSITIVE_SLIPPAGE_FEE_TRANSFORMER_GAS = new BigNumber(20000);
export const DEFAULT_FEE_ESTIMATE = { gas: 0, fee: ZERO_AMOUNT };
// tslint:enable:custom-no-magic-numbers
export const DEFAULT_GET_MARKET_ORDERS_OPTS: Omit<GetMarketOrdersOpts, 'gasPrice'> = {
// tslint:disable-next-line: custom-no-magic-numbers
runLimit: 2 ** 15,
excludedSources: [],
excludedFeeSources: [],
@@ -2767,7 +2604,7 @@ export const DEFAULT_GET_MARKET_ORDERS_OPTS: Omit<GetMarketOrdersOpts, 'gasPrice
allowFallback: true,
shouldGenerateQuoteReport: true,
shouldIncludePriceComparisonsReport: false,
tokenAdjacencyGraph: TokenAdjacencyGraph.getEmptyGraph(),
tokenAdjacencyGraph: { default: [] },
neonRouterNumSamples: 14,
fillAdjustor: new IdentityFillAdjustor(),
};

View File

@@ -29,6 +29,7 @@ import {
PriceComparisonsReport,
QuoteReport,
} from './../quote_report_generator';
import { getComparisonPrices } from './comparison_price';
import {
BUY_SOURCE_FILTER_BY_CHAIN_ID,
@@ -861,9 +862,14 @@ export class MarketOperationUtils {
}
private async _refreshPoolCacheIfRequiredAsync(takerToken: string, makerToken: string): Promise<void> {
_.values(this._sampler.poolsCaches)
.filter(cache => cache !== undefined && !cache.isFresh(takerToken, makerToken))
.forEach(cache => cache?.getFreshPoolsForPairAsync(takerToken, makerToken));
void Promise.all(
Object.values(this._sampler.poolsCaches).map(async cache => {
if (!cache || cache.isFresh(takerToken, makerToken)) {
return Promise.resolve([]);
}
return cache.getFreshPoolsForPairAsync(takerToken, makerToken);
}),
);
}
}

View File

@@ -12,8 +12,26 @@ import {
FillAdjustor,
MarketSideLiquidity,
MultiHopFillData,
TokenAdjacencyGraph,
} from './types';
/**
* Given a token pair, returns the intermediate tokens to consider for two-hop routes.
*/
export function getIntermediateTokens(
makerToken: string,
takerToken: string,
tokenAdjacencyGraph: TokenAdjacencyGraph,
): string[] {
const intermediateTokens = _.union(
_.get(tokenAdjacencyGraph, takerToken, tokenAdjacencyGraph.default),
_.get(tokenAdjacencyGraph, makerToken, tokenAdjacencyGraph.default),
);
return _.uniqBy(intermediateTokens, a => a.toLowerCase()).filter(
token => token.toLowerCase() !== makerToken.toLowerCase() && token.toLowerCase() !== takerToken.toLowerCase(),
);
}
/**
* Returns the best two-hop quote and the fee-adjusted rate of that quote.
*/

View File

@@ -8,6 +8,7 @@ import { MAX_UINT256, ZERO_AMOUNT } from './constants';
import {
AaveV2FillData,
AggregationError,
BalancerFillData,
BalancerV2BatchSwapFillData,
BalancerV2FillData,
BancorFillData,
@@ -37,12 +38,10 @@ import {
OrderDomain,
PlatypusFillData,
ShellFillData,
SynthetixFillData,
UniswapV2FillData,
UniswapV3FillData,
UniswapV3PathAmount,
VelodromeFillData,
WOOFiFillData,
} from './types';
// tslint:disable completed-docs
@@ -100,6 +99,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.Bancor, 'Bancor');
case ERC20BridgeSource.Curve:
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Curve');
case ERC20BridgeSource.Cream:
return encodeBridgeSourceId(BridgeProtocol.Balancer, 'Cream');
case ERC20BridgeSource.CryptoCom:
return encodeBridgeSourceId(BridgeProtocol.CryptoCom, 'CryptoCom');
case ERC20BridgeSource.Dodo:
@@ -209,10 +210,6 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.BancorV3, 'BancorV3');
case ERC20BridgeSource.Velodrome:
return encodeBridgeSourceId(BridgeProtocol.Velodrome, 'Velodrome');
case ERC20BridgeSource.Synthetix:
return encodeBridgeSourceId(BridgeProtocol.Synthetix, 'Synthetix');
case ERC20BridgeSource.WOOFi:
return encodeBridgeSourceId(BridgeProtocol.WOOFi, 'WOOFi');
default:
throw new Error(AggregationError.NoBridgeForSource);
}
@@ -255,6 +252,10 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
]);
break;
case ERC20BridgeSource.Balancer:
case ERC20BridgeSource.Cream:
const balancerFillData = (order as OptimizedMarketBridgeOrder<BalancerFillData>).fillData;
bridgeData = encoder.encode([balancerFillData.poolAddress]);
break;
case ERC20BridgeSource.BalancerV2:
{
const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2BatchSwapFillData>).fillData;
@@ -390,18 +391,6 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
const velodromeFillData = (order as OptimizedMarketBridgeOrder<VelodromeFillData>).fillData;
bridgeData = encoder.encode([velodromeFillData.router, velodromeFillData.stable]);
break;
case ERC20BridgeSource.Synthetix:
const fillData = (order as OptimizedMarketBridgeOrder<SynthetixFillData>).fillData;
bridgeData = encoder.encode([
fillData.synthetix,
fillData.takerTokenSymbolBytes32,
fillData.makerTokenSymbolBytes32,
]);
break;
case ERC20BridgeSource.WOOFi:
const woofiFillData = (order as OptimizedMarketBridgeOrder<WOOFiFillData>).fillData;
bridgeData = encoder.encode([woofiFillData.poolAddress]);
break;
default:
throw new Error(AggregationError.NoBridgeForSource);
}
@@ -498,6 +487,7 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.Mooniswap]: poolEncoder,
[ERC20BridgeSource.MStable]: poolEncoder,
[ERC20BridgeSource.Balancer]: poolEncoder,
[ERC20BridgeSource.Cream]: poolEncoder,
[ERC20BridgeSource.Uniswap]: poolEncoder,
// Custom integrations
[ERC20BridgeSource.MakerPsm]: makerPsmEncoder,
@@ -527,8 +517,6 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'),
[ERC20BridgeSource.Geist]: AbiEncoder.create('(address,address)'),
[ERC20BridgeSource.Velodrome]: AbiEncoder.create('(address,bool)'),
[ERC20BridgeSource.Synthetix]: AbiEncoder.create('(address,bytes32,bytes32)'),
[ERC20BridgeSource.WOOFi]: AbiEncoder.create('(address)'),
};
function getFillTokenAmounts(fill: Fill, side: MarketOperation): [BigNumber, BigNumber] {

View File

@@ -14,7 +14,7 @@ import { dexSampleToFill, ethToOutputAmount, nativeOrderToFill } from './fills';
import { Path, PathPenaltyOpts } from './path';
import { DexSample, ERC20BridgeSource, FeeSchedule, Fill, FillAdjustor, FillData, SamplerMetrics } from './types';
// tslint:disable: prefer-for-of completed-docs no-bitwise
// tslint:disable: prefer-for-of custom-no-magic-numbers completed-docs no-bitwise
// NOTE: The Rust router will panic with less than 3 samples
const MIN_NUM_SAMPLE_INPUTS = 3;

View File

@@ -1,19 +1,16 @@
import { ChainId } from '@0x/contract-addresses';
import { getPoolsWithTokens, parsePoolData } from 'balancer-labs-sor-v1';
import { Pool } from 'balancer-labs-sor-v1/dist/types';
import { gql, request } from 'graphql-request';
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
import { LogFunction } from '../../../types';
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_TOP_POOLS_FETCHED } from '../constants';
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_SUBGRAPH_URL, BALANCER_TOP_POOLS_FETCHED } from '../constants';
import { NoOpPoolsCache } from './no_op_pools_cache';
import { AbstractPoolsCache, CacheValue, PoolsCache } from './pools_cache';
import { CacheValue, PoolsCache } from './pools_cache';
// tslint:disable:custom-no-magic-numbers
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
// tslint:disable: member-ordering
const BALANCER_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer';
// tslint:enable:custom-no-magic-numbers
interface BalancerPoolResponse {
id: string;
@@ -23,18 +20,10 @@ interface BalancerPoolResponse {
totalWeight: string;
}
export class BalancerPoolsCache extends AbstractPoolsCache {
public static create(chainId: ChainId): PoolsCache {
if (chainId !== ChainId.Mainnet) {
return new NoOpPoolsCache();
}
return new BalancerPoolsCache();
}
private constructor(
export class BalancerPoolsCache extends PoolsCache {
constructor(
private readonly _subgraphUrl: string = BALANCER_SUBGRAPH_URL,
cache: Map<string, CacheValue> = new Map(),
cache: { [key: string]: CacheValue } = {},
private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
private readonly _topPoolsFetched: number = BALANCER_TOP_POOLS_FETCHED,
private readonly _warningLogger: LogFunction = DEFAULT_WARNING_LOGGER,

View File

@@ -6,18 +6,16 @@ import { gql, request } from 'graphql-request';
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
import { LogFunction } from '../../../types';
import { BALANCER_MAX_POOLS_FETCHED, BALANCER_TOP_POOLS_FETCHED } from '../constants';
import {
BALANCER_MAX_POOLS_FETCHED,
BALANCER_TOP_POOLS_FETCHED,
BALANCER_V2_SUBGRAPH_URL_BY_CHAIN,
} from '../constants';
import { parsePoolData } from './balancer_sor_v2';
import { NoOpPoolsCache } from './no_op_pools_cache';
import { AbstractPoolsCache, CacheValue, PoolsCache } from './pools_cache';
// tslint:disable: member-ordering
const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = new Map<ChainId, string>([
[ChainId.Fantom, 'https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx'],
]);
import { CacheValue, PoolsCache } from './pools_cache';
// tslint:disable-next-line:custom-no-magic-numbers
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
interface BalancerPoolResponse {
@@ -30,16 +28,7 @@ interface BalancerPoolResponse {
amp: string | null;
}
export class BalancerV2PoolsCache extends AbstractPoolsCache {
public static createBeethovenXPoolCache(chainId: ChainId): PoolsCache {
const subgraphUrl = BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN.get(chainId);
if (subgraphUrl === undefined) {
return new NoOpPoolsCache();
}
return new BalancerV2PoolsCache(subgraphUrl);
}
export class BalancerV2PoolsCache extends PoolsCache {
private static _parseSubgraphPoolData(pool: any, takerToken: string, makerToken: string): Pool {
const tToken = pool.tokens.find((t: any) => t.address === takerToken);
const mToken = pool.tokens.find((t: any) => t.address === makerToken);
@@ -60,12 +49,13 @@ export class BalancerV2PoolsCache extends AbstractPoolsCache {
};
}
private constructor(
private readonly subgraphUrl: string,
constructor(
chainId: 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,
cache: Map<string, CacheValue> = new Map(),
cache: { [key: string]: CacheValue } = {},
) {
super(cache);
void this._loadTopPoolsAsync();
@@ -73,6 +63,19 @@ export class BalancerV2PoolsCache extends AbstractPoolsCache {
setInterval(async () => void this._loadTopPoolsAsync(), ONE_DAY_MS / 2);
}
// protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
// try {
// const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
// // Sort by maker token balance (descending)
// const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
// b.balanceOut.minus(a.balanceOut).toNumber(),
// );
// return pools.length > this.maxPoolsFetched ? pools.slice(0, this.maxPoolsFetched) : pools;
// } catch (err) {
// return [];
// }
// }
protected async _fetchTopPoolsAsync(): Promise<BalancerPoolResponse[]> {
const query = gql`
query fetchTopPools($topPoolsFetched: Int!) {

View File

@@ -20,6 +20,7 @@ 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 {

View File

@@ -0,0 +1,28 @@
import { Pool } from 'balancer-labs-sor-v1/dist/types';
import { getPoolsWithTokens, parsePoolData } from 'cream-sor';
import { BALANCER_MAX_POOLS_FETCHED } from '../constants';
import { CacheValue, PoolsCache } from './pools_cache';
export class CreamPoolsCache extends PoolsCache {
constructor(
_cache: { [key: string]: CacheValue } = {},
private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
) {
super(_cache);
}
protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
try {
const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
// Sort by maker token balance (descending)
const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
b.balanceOut.minus(a.balanceOut).toNumber(),
);
return pools.slice(0, this.maxPoolsFetched);
} catch (err) {
return [];
}
}
}

View File

@@ -1,3 +1,4 @@
export { BalancerPoolsCache } from './balancer_pools_cache';
export { BalancerV2PoolsCache } from './balancer_v2_pools_cache';
export { AbstractPoolsCache, PoolsCache } from './pools_cache';
export { BalancerPoolsCache } from './balancer_utils';
export { BalancerV2PoolsCache } from './balancer_v2_utils';
export { CreamPoolsCache } from './cream_utils';
export { PoolsCache } from './pools_cache';

View File

@@ -1,21 +0,0 @@
import { Pool, PoolsCache } from './pools_cache';
// tslint:disable:prefer-function-over-method
export class NoOpPoolsCache implements PoolsCache {
public async getFreshPoolsForPairAsync(
_takerToken: string,
_makerToken: string,
_timeoutMs?: number | undefined,
): Promise<Pool[]> {
return [];
}
public getPoolAddressesForPair(_takerToken: string, _makerToken: string): string[] {
return [];
}
public isFresh(_takerToken: string, _makerToken: string): boolean {
return true;
}
}

View File

@@ -1,15 +1,18 @@
import { ONE_HOUR_IN_SECONDS, ONE_SECOND_MS } from '../constants';
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.

View File

@@ -7,30 +7,18 @@ export interface CacheValue {
pools: Pool[];
}
// tslint:disable:custom-no-magic-numbers
// Cache results for 30mins
const DEFAULT_CACHE_TIME_MS = (ONE_HOUR_IN_SECONDS / 2) * ONE_SECOND_MS;
const DEFAULT_TIMEOUT_MS = 3000;
const DEFAULT_TIMEOUT_MS = 1000;
// tslint:enable:custom-no-magic-numbers
export interface PoolsCache {
getFreshPoolsForPairAsync(takerToken: string, makerToken: string, timeoutMs?: number): Promise<Pool[]>;
getPoolAddressesForPair(takerToken: string, makerToken: string): string[];
isFresh(takerToken: string, makerToken: string): boolean;
}
export abstract class AbstractPoolsCache implements PoolsCache {
protected static _getKey(takerToken: string, makerToken: string): string {
return `${takerToken}-${makerToken}`;
}
protected static _isExpired(value: CacheValue | undefined): boolean {
if (value === undefined) {
return true;
}
export abstract class PoolsCache {
protected static _isExpired(value: CacheValue): boolean {
return Date.now() >= value.expiresAt;
}
constructor(
protected readonly _cache: Map<string, CacheValue>,
protected readonly _cache: { [key: string]: CacheValue },
protected readonly _cacheTimeMs: number = DEFAULT_CACHE_TIME_MS,
) {}
@@ -43,42 +31,47 @@ export abstract class AbstractPoolsCache implements PoolsCache {
return Promise.race([this._getAndSaveFreshPoolsForPairAsync(takerToken, makerToken), timeout]);
}
/**
* Returns pool addresses (can be stale) for a pair.
*
* An empty array will be returned if cache does not exist.
*/
public getPoolAddressesForPair(takerToken: string, makerToken: string): string[] {
const value = this._getValue(takerToken, makerToken);
return value === undefined ? [] : value.pools.map(pool => pool.id);
public getCachedPoolAddressesForPair(
takerToken: string,
makerToken: string,
ignoreExpired: boolean = true,
): string[] | undefined {
const key = JSON.stringify([takerToken, makerToken]);
const value = this._cache[key];
if (ignoreExpired) {
return value === undefined ? [] : value.pools.map(pool => pool.id);
}
if (!value) {
return undefined;
}
if (PoolsCache._isExpired(value)) {
return undefined;
}
return (value || []).pools.map(pool => pool.id);
}
public isFresh(takerToken: string, makerToken: string): boolean {
const value = this._getValue(takerToken, makerToken);
return !AbstractPoolsCache._isExpired(value);
}
protected _getValue(takerToken: string, makerToken: string): CacheValue | undefined {
const key = AbstractPoolsCache._getKey(takerToken, makerToken);
return this._cache.get(key);
const cached = this.getCachedPoolAddressesForPair(takerToken, makerToken, false);
return cached !== undefined;
}
protected async _getAndSaveFreshPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
const key = AbstractPoolsCache._getKey(takerToken, makerToken);
const value = this._cache.get(key);
if (!AbstractPoolsCache._isExpired(value)) {
return value!.pools;
const key = JSON.stringify([takerToken, makerToken]);
const value = this._cache[key];
if (value === undefined || value.expiresAt >= Date.now()) {
const pools = await this._fetchPoolsForPairAsync(takerToken, makerToken);
const expiresAt = Date.now() + this._cacheTimeMs;
this._cachePoolsForPair(takerToken, makerToken, pools, expiresAt);
}
const pools = await this._fetchPoolsForPairAsync(takerToken, makerToken);
const expiresAt = Date.now() + this._cacheTimeMs;
this._cachePoolsForPair(takerToken, makerToken, pools, expiresAt);
return pools;
return this._cache[key].pools;
}
protected _cachePoolsForPair(takerToken: string, makerToken: string, pools: Pool[], expiresAt: number): void {
const key = AbstractPoolsCache._getKey(takerToken, makerToken);
this._cache.set(key, { pools, expiresAt });
const key = JSON.stringify([takerToken, makerToken]);
this._cache[key] = {
pools,
expiresAt,
};
}
protected abstract _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]>;

View File

@@ -3,11 +3,10 @@ import { BigNumber, NULL_BYTES } from '@0x/utils';
import { SamplerOverrides } from '../../types';
import { ERC20BridgeSamplerContract } from '../../wrappers';
import { TokenAdjacencyGraph } from '../token_adjacency_graph';
import { BancorService } from './bancor_service';
import { PoolsCacheMap, SamplerOperations } from './sampler_operations';
import { BatchedOperation, LiquidityProviderRegistry } from './types';
import { BatchedOperation, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
/**
* Generate sample amounts up to `maxFillAmount`.

View File

@@ -1,14 +1,12 @@
import { ChainId } from '@0x/contract-addresses';
import { LimitOrderFields } from '@0x/protocol-utils';
import { BigNumber, logUtils } from '@0x/utils';
import { formatBytes32String } from '@ethersproject/strings';
import * as _ from 'lodash';
import { AaveV2Sampler } from '../../noop_samplers/AaveV2Sampler';
import { GeistSampler } from '../../noop_samplers/GeistSampler';
import { SamplerCallResult, SignedNativeOrder } from '../../types';
import { ERC20BridgeSamplerContract } from '../../wrappers';
import { TokenAdjacencyGraph } from '../token_adjacency_graph';
import { AaveV2ReservesCache } from './aave_reserves_cache';
import { BancorService } from './bancor_service';
@@ -26,9 +24,10 @@ 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,
BANCOR_REGISTRY_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,
@@ -47,19 +46,16 @@ import {
NULL_ADDRESS,
PLATYPUS_ROUTER_BY_CHAIN_ID,
SELL_SOURCE_FILTER_BY_CHAIN_ID,
SYNTHETIX_CURRENCY_KEYS_BY_CHAIN_ID,
SYNTHETIX_READ_PROXY_BY_CHAIN_ID,
UNISWAPV1_ROUTER_BY_CHAIN_ID,
UNISWAPV3_CONFIG_BY_CHAIN_ID,
VELODROME_ROUTER_BY_CHAIN_ID,
WOOFI_POOL_BY_CHAIN_ID,
WOOFI_SUPPORTED_TOKENS,
ZERO_AMOUNT,
} from './constants';
import { getGeistInfoForPair } from './geist_utils';
import { getLiquidityProvidersForPair } from './liquidity_provider_utils';
import { BalancerPoolsCache, BalancerV2PoolsCache, PoolsCache } from './pools_cache';
import { BalancerV2SwapInfoCache } from './pools_cache/balancer_v2_swap_info_cache';
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';
@@ -97,11 +93,11 @@ import {
PsmInfo,
ShellFillData,
SourceQuoteOperation,
SynthetixFillData,
SourcesWithPoolsCache,
TokenAdjacencyGraph,
UniswapV2FillData,
UniswapV3FillData,
VelodromeFillData,
WOOFiFillData,
} from './types';
/**
@@ -116,11 +112,9 @@ export const TWO_HOP_SOURCE_FILTERS = SourceFilters.all().exclude([
*/
export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSource.MultiHop, ERC20BridgeSource.Native]);
export interface PoolsCacheMap {
[ERC20BridgeSource.Balancer]: PoolsCache;
export type PoolsCacheMap = { [key in Exclude<SourcesWithPoolsCache, ERC20BridgeSource.BalancerV2>]: PoolsCache } & {
[ERC20BridgeSource.BalancerV2]: BalancerV2SwapInfoCache | undefined;
[ERC20BridgeSource.Beethovenx]: PoolsCache;
}
};
// tslint:disable:no-inferred-empty-object-type no-unbound-method
@@ -146,7 +140,7 @@ export class SamplerOperations {
public readonly chainId: ChainId,
protected readonly _samplerContract: ERC20BridgeSamplerContract,
poolsCaches?: PoolsCacheMap,
protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = TokenAdjacencyGraph.getEmptyGraph(),
protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] },
liquidityProviderRegistry: LiquidityProviderRegistry = {},
bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
) {
@@ -157,8 +151,12 @@ export class SamplerOperations {
this.poolsCaches = poolsCaches
? poolsCaches
: {
[ERC20BridgeSource.Beethovenx]: BalancerV2PoolsCache.createBeethovenXPoolCache(chainId),
[ERC20BridgeSource.Balancer]: BalancerPoolsCache.create(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
@@ -812,7 +810,7 @@ export class SamplerOperations {
if (_sources.length === 0) {
return SamplerOperations.constant([]);
}
const intermediateTokens = this.tokenAdjacencyGraph.getIntermediateTokens(makerToken, takerToken);
const intermediateTokens = getIntermediateTokens(makerToken, takerToken, this.tokenAdjacencyGraph);
const subOps = intermediateTokens.map(intermediateToken => {
const firstHopOps = this._getSellQuoteOperations(_sources, intermediateToken, takerToken, [ZERO_AMOUNT]);
const secondHopOps = this._getSellQuoteOperations(_sources, makerToken, intermediateToken, [ZERO_AMOUNT]);
@@ -867,7 +865,7 @@ export class SamplerOperations {
if (_sources.length === 0) {
return SamplerOperations.constant([]);
}
const intermediateTokens = this.tokenAdjacencyGraph.getIntermediateTokens(makerToken, takerToken);
const intermediateTokens = getIntermediateTokens(makerToken, takerToken, this.tokenAdjacencyGraph);
const subOps = intermediateTokens.map(intermediateToken => {
const firstHopOps = this._getBuyQuoteOperations(_sources, intermediateToken, takerToken, [
new BigNumber(0),
@@ -1312,91 +1310,6 @@ export class SamplerOperations {
});
}
public getSynthetixSellQuotes(
readProxy: string,
takerTokenSymbol: string,
makerTokenSymbol: string,
takerFillAmounts: BigNumber[],
): SourceQuoteOperation<SynthetixFillData> {
const takerTokenSymbolBytes32 = formatBytes32String(takerTokenSymbol);
const makerTokenSymbolBytes32 = formatBytes32String(makerTokenSymbol);
return new SamplerContractOperation({
source: ERC20BridgeSource.Synthetix,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromSynthetix,
params: [readProxy, takerTokenSymbolBytes32, makerTokenSymbolBytes32, takerFillAmounts],
callback: (callResults: string, fillData: SynthetixFillData): BigNumber[] => {
const [synthetix, samples] = this._samplerContract.getABIDecodedReturnData<[string, BigNumber[]]>(
'sampleSellsFromSynthetix',
callResults,
);
fillData.synthetix = synthetix;
fillData.takerTokenSymbolBytes32 = takerTokenSymbolBytes32;
fillData.makerTokenSymbolBytes32 = makerTokenSymbolBytes32;
fillData.chainId = this.chainId;
return samples;
},
});
}
public getSynthetixBuyQuotes(
readProxy: string,
takerTokenSymbol: string,
makerTokenSymbol: string,
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<SynthetixFillData> {
const takerTokenSymbolBytes32 = formatBytes32String(takerTokenSymbol);
const makerTokenSymbolBytes32 = formatBytes32String(makerTokenSymbol);
return new SamplerContractOperation({
source: ERC20BridgeSource.Synthetix,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromSynthetix,
params: [readProxy, takerTokenSymbolBytes32, makerTokenSymbolBytes32, makerFillAmounts],
callback: (callResults: string, fillData: SynthetixFillData): BigNumber[] => {
const [synthetix, samples] = this._samplerContract.getABIDecodedReturnData<[string, BigNumber[]]>(
'sampleBuysFromSynthetix',
callResults,
);
fillData.synthetix = synthetix;
fillData.takerTokenSymbolBytes32 = takerTokenSymbolBytes32;
fillData.makerTokenSymbolBytes32 = makerTokenSymbolBytes32;
fillData.chainId = this.chainId;
return samples;
},
});
}
public getWOOFiSellQuotes(
poolAddress: string,
takerToken: string,
makerToken: string,
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<WOOFiFillData> {
const chainId = this.chainId;
return new SamplerContractOperation({
fillData: { poolAddress, takerToken, makerToken, chainId },
source: ERC20BridgeSource.WOOFi,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromWooPP,
params: [poolAddress, takerToken, makerToken, makerFillAmounts],
});
}
public getWOOFiBuyQuotes(
poolAddress: string,
takerToken: string,
makerToken: string,
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<WOOFiFillData> {
const chainId = this.chainId;
return new SamplerContractOperation({
fillData: { poolAddress, takerToken, makerToken, chainId },
source: ERC20BridgeSource.WOOFi,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromWooPP,
params: [poolAddress, takerToken, makerToken, makerFillAmounts],
});
}
/**
* Returns the best price for the native token
* Best is calculated according to the fee schedule, so the price of the
@@ -1412,13 +1325,9 @@ export class SamplerOperations {
if (makerToken.toLowerCase() === nativeToken.toLowerCase()) {
return SamplerOperations.constant(new BigNumber(1));
}
const subOps = this._getSellQuoteOperations(
sources,
makerToken,
nativeToken,
[nativeFillAmount],
TokenAdjacencyGraph.getEmptyGraph(),
);
const subOps = this._getSellQuoteOperations(sources, makerToken, nativeToken, [nativeFillAmount], {
default: [],
});
return this._createBatch(
subOps,
(samples: BigNumber[][]) => {
@@ -1514,7 +1423,7 @@ export class SamplerOperations {
): SourceQuoteOperation[] {
// 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 = tokenAdjacencyGraph.getIntermediateTokens(makerToken, takerToken);
const intermediateTokens = getIntermediateTokens(makerToken, takerToken, tokenAdjacencyGraph);
// Drop out MultiHop and Native as we do not query those here.
const _sources = SELL_SOURCE_FILTER_BY_CHAIN_ID[this.chainId]
.exclude([ERC20BridgeSource.MultiHop, ERC20BridgeSource.Native])
@@ -1624,17 +1533,20 @@ export class SamplerOperations {
),
];
case ERC20BridgeSource.Balancer:
return this.poolsCaches[ERC20BridgeSource.Balancer]
.getPoolAddressesForPair(takerToken, makerToken)
.map(balancerPool =>
this.getBalancerSellQuotes(
balancerPool,
makerToken,
takerToken,
takerFillAmounts,
ERC20BridgeSource.Balancer,
),
);
return (
this.poolsCaches[ERC20BridgeSource.Balancer].getCachedPoolAddressesForPair(
takerToken,
makerToken,
) || []
).map(balancerPool =>
this.getBalancerSellQuotes(
balancerPool,
makerToken,
takerToken,
takerFillAmounts,
ERC20BridgeSource.Balancer,
),
);
case ERC20BridgeSource.BalancerV2: {
const cache = this.poolsCaches[source];
if (!cache) {
@@ -1652,15 +1564,16 @@ export class SamplerOperations {
);
}
case ERC20BridgeSource.Beethovenx: {
const cache = this.poolsCaches[source];
const poolAddresses = cache.getPoolAddressesForPair(takerToken, makerToken);
const poolIds =
this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
const vault = BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
if (vault === NULL_ADDRESS) {
return [];
}
return poolAddresses.map(poolAddress =>
return poolIds.map(poolId =>
this.getBalancerV2SellQuotes(
{ poolId: poolAddress, vault },
{ poolId, vault },
makerToken,
takerToken,
takerFillAmounts,
@@ -1668,6 +1581,21 @@ export class SamplerOperations {
),
);
}
case ERC20BridgeSource.Cream:
return (
this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
takerToken,
makerToken,
) || []
).map(creamPool =>
this.getBalancerSellQuotes(
creamPool,
makerToken,
takerToken,
takerFillAmounts,
ERC20BridgeSource.Cream,
),
);
case ERC20BridgeSource.Dodo:
if (!isValidAddress(DODOV1_CONFIG_BY_CHAIN_ID[this.chainId].registry)) {
return [];
@@ -1767,8 +1695,8 @@ export class SamplerOperations {
);
}
case ERC20BridgeSource.GMX: {
// MIM has no liquidity.
if (takerToken === AVALANCHE_TOKENS.MIM || makerToken === AVALANCHE_TOKENS.MIM) {
// low liquidity mim pool dont quote
if (takerToken === AVALANCHE_TOKENS.MIM || makerToken === 'AVALANCHE_TOKENS.MIM') {
return [];
}
return this.getGMXSellQuotes(
@@ -1805,32 +1733,6 @@ export class SamplerOperations {
takerFillAmounts,
);
}
case ERC20BridgeSource.Synthetix: {
const readProxy = SYNTHETIX_READ_PROXY_BY_CHAIN_ID[this.chainId];
const currencyKeyMap = SYNTHETIX_CURRENCY_KEYS_BY_CHAIN_ID[this.chainId];
const takerTokenSymbol = currencyKeyMap.get(takerToken.toLowerCase());
const makerTokenSymbol = currencyKeyMap.get(makerToken.toLowerCase());
if (takerTokenSymbol === undefined || makerTokenSymbol === undefined) {
return [];
}
return this.getSynthetixSellQuotes(
readProxy,
takerTokenSymbol,
makerTokenSymbol,
takerFillAmounts,
);
}
case ERC20BridgeSource.WOOFi: {
if (!(WOOFI_SUPPORTED_TOKENS.has(takerToken) && WOOFI_SUPPORTED_TOKENS.has(makerToken))) {
return [];
}
return this.getWOOFiSellQuotes(
WOOFI_POOL_BY_CHAIN_ID[this.chainId],
takerToken,
makerToken,
takerFillAmounts,
);
}
default:
throw new Error(`Unsupported sell sample source: ${source}`);
}
@@ -1865,7 +1767,7 @@ export class SamplerOperations {
): SourceQuoteOperation[] {
// 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 = this.tokenAdjacencyGraph.getIntermediateTokens(makerToken, takerToken);
const intermediateTokens = getIntermediateTokens(makerToken, takerToken, this.tokenAdjacencyGraph);
const _sources = BATCH_SOURCE_FILTERS.getAllowed(sources);
return _.flatten(
_sources.map((source): SourceQuoteOperation | SourceQuoteOperation[] => {
@@ -1969,17 +1871,20 @@ export class SamplerOperations {
),
];
case ERC20BridgeSource.Balancer:
return this.poolsCaches[ERC20BridgeSource.Balancer]
.getPoolAddressesForPair(takerToken, makerToken)
.map(poolAddress =>
this.getBalancerBuyQuotes(
poolAddress,
makerToken,
takerToken,
makerFillAmounts,
ERC20BridgeSource.Balancer,
),
);
return (
this.poolsCaches[ERC20BridgeSource.Balancer].getCachedPoolAddressesForPair(
takerToken,
makerToken,
) || []
).map(poolAddress =>
this.getBalancerBuyQuotes(
poolAddress,
makerToken,
takerToken,
makerFillAmounts,
ERC20BridgeSource.Balancer,
),
);
case ERC20BridgeSource.BalancerV2: {
const cache = this.poolsCaches[source];
if (!cache) {
@@ -2003,8 +1908,9 @@ export class SamplerOperations {
);
}
case ERC20BridgeSource.Beethovenx: {
const cache = this.poolsCaches[source];
const poolIds = cache.getPoolAddressesForPair(takerToken, makerToken) || [];
const poolIds =
this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
const vault = BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
if (vault === NULL_ADDRESS) {
return [];
@@ -2019,6 +1925,21 @@ export class SamplerOperations {
),
);
}
case ERC20BridgeSource.Cream:
return (
this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
takerToken,
makerToken,
) || []
).map(poolAddress =>
this.getBalancerBuyQuotes(
poolAddress,
makerToken,
takerToken,
makerFillAmounts,
ERC20BridgeSource.Cream,
),
);
case ERC20BridgeSource.Dodo:
if (!isValidAddress(DODOV1_CONFIG_BY_CHAIN_ID[this.chainId].registry)) {
return [];
@@ -2106,8 +2027,8 @@ export class SamplerOperations {
return this.getCompoundBuyQuotes(cToken.tokenAddress, makerToken, takerToken, makerFillAmounts);
}
case ERC20BridgeSource.GMX: {
// MIM has no liquidity.
if (takerToken === AVALANCHE_TOKENS.MIM || makerToken === AVALANCHE_TOKENS.MIM) {
// bad mim pool dont quote
if (takerToken === 'AVALANCHE_TOKENS.MIM' || makerToken === 'AVALANCHE_TOKENS.MIM') {
return [];
}
return this.getGMXBuyQuotes(
@@ -2144,32 +2065,6 @@ export class SamplerOperations {
makerFillAmounts,
);
}
case ERC20BridgeSource.Synthetix: {
const readProxy = SYNTHETIX_READ_PROXY_BY_CHAIN_ID[this.chainId];
const currencyKeyMap = SYNTHETIX_CURRENCY_KEYS_BY_CHAIN_ID[this.chainId];
const takerTokenSymbol = currencyKeyMap.get(takerToken.toLowerCase());
const makerTokenSymbol = currencyKeyMap.get(makerToken.toLowerCase());
if (takerTokenSymbol === undefined || makerTokenSymbol === undefined) {
return [];
}
return this.getSynthetixBuyQuotes(
readProxy,
takerTokenSymbol,
makerTokenSymbol,
makerFillAmounts,
);
}
case ERC20BridgeSource.WOOFi: {
if (!(WOOFI_SUPPORTED_TOKENS.has(takerToken) && WOOFI_SUPPORTED_TOKENS.has(makerToken))) {
return [];
}
return this.getWOOFiBuyQuotes(
WOOFI_POOL_BY_CHAIN_ID[this.chainId],
takerToken,
makerToken,
makerFillAmounts,
);
}
default:
throw new Error(`Unsupported buy sample source: ${source}`);
}

View File

@@ -1,7 +1,7 @@
import { ChainId } from '@0x/contract-addresses';
import {
FillQuoteTransformerLimitOrderInfo,
FillQuoteTransformerOrderType,
FillQuoteTransformerOtcOrderInfo,
FillQuoteTransformerRfqOrderInfo,
} from '@0x/protocol-utils';
import { MarketOperation } from '@0x/types';
@@ -11,7 +11,6 @@ import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts }
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor';
import { IRfqClient } from '../irfq_client';
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator';
import { TokenAdjacencyGraph } from '../token_adjacency_graph';
import { SourceFilters } from './source_filters';
@@ -45,6 +44,7 @@ export enum ERC20BridgeSource {
MultiBridge = 'MultiBridge',
Balancer = 'Balancer',
BalancerV2 = 'Balancer_V2',
Cream = 'CREAM',
Bancor = 'Bancor',
MakerPsm = 'MakerPsm',
MStable = 'mStable',
@@ -67,8 +67,6 @@ export enum ERC20BridgeSource {
Compound = 'Compound',
Synapse = 'Synapse',
BancorV3 = 'BancorV3',
Synthetix = 'Synthetix',
WOOFi = 'WOOFi',
// BSC only
PancakeSwap = 'PancakeSwap',
PancakeSwapV2 = 'PancakeSwap_V2',
@@ -108,6 +106,11 @@ export enum ERC20BridgeSource {
// Optimism
Velodrome = 'Velodrome',
}
export type SourcesWithPoolsCache =
| ERC20BridgeSource.Balancer
| ERC20BridgeSource.BalancerV2
| ERC20BridgeSource.Beethovenx
| ERC20BridgeSource.Cream;
// tslint:disable: enum-naming
/**
@@ -194,7 +197,8 @@ export interface FillData {}
// `FillData` for native fills. Represents a single native order
export type NativeRfqOrderFillData = FillQuoteTransformerRfqOrderInfo;
export type NativeLimitOrderFillData = FillQuoteTransformerLimitOrderInfo;
export type NativeFillData = NativeRfqOrderFillData | NativeLimitOrderFillData;
export type NativeOtcOrderFillData = FillQuoteTransformerOtcOrderInfo;
export type NativeFillData = NativeRfqOrderFillData | NativeLimitOrderFillData | NativeOtcOrderFillData;
// Represents an individual DEX sample from the sampler contract
export interface DexSample<TFillData extends FillData = FillData> {
@@ -373,27 +377,11 @@ export interface PlatypusFillData extends FillData {
tokenAddressPath: string[];
}
export interface WOOFiFillData extends FillData {
poolAddress: string;
takerToken: string;
makerToken: string;
// Only needed for gas estimation
chainId: ChainId;
}
export interface VelodromeFillData extends FillData {
router: string;
stable: boolean;
}
export interface SynthetixFillData extends FillData {
synthetix: string;
takerTokenSymbolBytes32: string;
makerTokenSymbolBytes32: string;
// Only needed for gas estimation.
chainId: ChainId;
}
/**
* Represents a node on a fill path.
*/
@@ -450,7 +438,8 @@ export interface OptimizedRfqOrder extends OptimizedMarketOrderBase<NativeRfqOrd
export type OptimizedMarketOrder =
| OptimizedMarketBridgeOrder<FillData>
| OptimizedMarketOrderBase<NativeLimitOrderFillData>
| OptimizedMarketOrderBase<NativeRfqOrderFillData>;
| OptimizedMarketOrderBase<NativeRfqOrderFillData>
| OptimizedMarketOrderBase<NativeOtcOrderFillData>;
export interface GetMarketOrdersRfqOpts extends RfqRequestOpts {
rfqClient?: IRfqClient;
@@ -625,6 +614,15 @@ export interface OptimizerResultWithReport extends OptimizerResult {
priceComparisonsReport?: PriceComparisonsReport;
}
export type MarketDepthSide = Array<Array<DexSample<FillData>>>;
export interface MarketDepth {
bids: MarketDepthSide;
asks: MarketDepthSide;
makerTokenDecimals: number;
takerTokenDecimals: number;
}
export interface MarketSideLiquidity {
side: MarketOperation;
inputAmount: BigNumber;
@@ -647,6 +645,11 @@ export interface RawQuotes {
dexQuotes: Array<Array<DexSample<FillData>>>;
}
export interface TokenAdjacencyGraph {
[token: string]: string[];
default: string[];
}
export interface LiquidityProviderRegistry {
[address: string]: {
tokens: string[];

View File

@@ -6,36 +6,28 @@ import { SwapQuoterError } from '../types';
const MAX_ERROR_COUNT = 5;
interface GasOracleResponse {
result: {
// gas price in wei
fast: number;
};
}
export class ProtocolFeeUtils {
private static _instance: ProtocolFeeUtils;
private readonly _zeroExGasApiUrl: string;
private readonly _ethGasStationUrl!: string;
private readonly _gasPriceHeart: any;
private _gasPriceEstimation: BigNumber = constants.ZERO_AMOUNT;
private _errorCount: number = 0;
public static getInstance(
gasPricePollingIntervalInMs: number,
zeroExGasApiUrl: string = constants.ZERO_EX_GAS_API_URL,
ethGasStationUrl: string = constants.ETH_GAS_STATION_API_URL,
initialGasPrice: BigNumber = constants.ZERO_AMOUNT,
): ProtocolFeeUtils {
if (!ProtocolFeeUtils._instance) {
ProtocolFeeUtils._instance = new ProtocolFeeUtils(
gasPricePollingIntervalInMs,
zeroExGasApiUrl,
ethGasStationUrl,
initialGasPrice,
);
}
return ProtocolFeeUtils._instance;
}
/** @returns gas price (in wei) */
public async getGasPriceEstimationOrThrowAsync(shouldHardRefresh?: boolean): Promise<BigNumber> {
if (this._gasPriceEstimation.eq(constants.ZERO_AMOUNT)) {
return this._getGasPriceFromGasStationOrThrowAsync();
@@ -56,21 +48,27 @@ export class ProtocolFeeUtils {
private constructor(
gasPricePollingIntervalInMs: number,
zeroExGasApiUrl: string = constants.ZERO_EX_GAS_API_URL,
ethGasStationUrl: string = constants.ETH_GAS_STATION_API_URL,
initialGasPrice: BigNumber = constants.ZERO_AMOUNT,
) {
this._gasPriceHeart = heartbeats.createHeart(gasPricePollingIntervalInMs);
this._gasPriceEstimation = initialGasPrice;
this._zeroExGasApiUrl = zeroExGasApiUrl;
this._ethGasStationUrl = ethGasStationUrl;
this._initializeHeartBeat();
}
// tslint:disable-next-line: prefer-function-over-method
private async _getGasPriceFromGasStationOrThrowAsync(): Promise<BigNumber> {
try {
const res = await fetch(this._zeroExGasApiUrl);
const gasInfo: GasOracleResponse = await res.json();
const gasPriceWei = new BigNumber(gasInfo.result.fast);
const res = await fetch(this._ethGasStationUrl);
const gasInfo = await res.json();
// Eth Gas Station result is gwei * 10
// tslint:disable-next-line:custom-no-magic-numbers
const BASE_TEN = 10;
const gasPriceGwei = new BigNumber(gasInfo.fast / BASE_TEN);
// tslint:disable-next-line:custom-no-magic-numbers
const unit = new BigNumber(BASE_TEN).pow(9);
const gasPriceWei = unit.times(gasPriceGwei);
// Reset the error count to 0 once we have a successful response
this._errorCount = 0;
return gasPriceWei;

View File

@@ -11,8 +11,6 @@ import {
FillData,
MultiHopFillData,
NativeFillData,
NativeLimitOrderFillData,
NativeRfqOrderFillData,
RawQuotes,
} from './market_operation_utils/types';
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from './quote_requestor';
@@ -353,7 +351,7 @@ function _isNativeOrderFromCollapsedFill(cf: Fill): cf is Fill<NativeFillData> {
*/
export function nativeOrderToReportEntry(
type: FillQuoteTransformerOrderType,
fillData: NativeLimitOrderFillData | NativeRfqOrderFillData,
fillData: NativeFillData,
fillableAmount: BigNumber,
comparisonPrice?: BigNumber | undefined,
quoteRequestor?: QuoteRequestor,

View File

@@ -1,84 +0,0 @@
import * as _ from 'lodash';
import { Address } from '../types';
export class TokenAdjacencyGraph {
private readonly _graph: Map<Address, Address[]>;
private readonly _defaultTokens: readonly Address[];
public static getEmptyGraph(): TokenAdjacencyGraph {
return new TokenAdjacencyGraphBuilder().build();
}
/** Prefer using {@link TokenAdjacencyGraphBuilder}. */
constructor(graph: Map<Address, Address[]>, defaultTokens: readonly Address[]) {
this._graph = graph;
this._defaultTokens = defaultTokens;
}
public getAdjacentTokens(fromToken: Address): readonly Address[] {
return this._graph.get(fromToken.toLowerCase()) || this._defaultTokens;
}
/** Given a token pair, returns the intermediate tokens to consider for two-hop routes. */
public getIntermediateTokens(takerToken: Address, makerToken: Address): Address[] {
// NOTE: it seems it should be a union of `to` tokens of `takerToken` and `from` tokens of `makerToken`,
// leaving it as same as the initial implementation for now.
return _.union(this.getAdjacentTokens(takerToken), this.getAdjacentTokens(makerToken)).filter(
token => token !== takerToken.toLowerCase() && token !== makerToken.toLowerCase(),
);
}
}
// tslint:disable-next-line: max-classes-per-file
export class TokenAdjacencyGraphBuilder {
private readonly _graph: Map<Address, Address[]>;
private readonly _defaultTokens: readonly Address[];
constructor(defaultTokens: readonly string[] = []) {
this._graph = new Map();
this._defaultTokens = defaultTokens.map(addr => addr.toLowerCase());
}
public add(fromToken: Address, toToken: Address): TokenAdjacencyGraphBuilder {
const fromLower = fromToken.toLowerCase();
const toLower = toToken.toLowerCase();
if (fromLower === toLower) {
throw new Error(`from token (${fromToken}) must be different from to token (${toToken})`);
}
if (!this._graph.has(fromLower)) {
this._graph.set(fromLower, [...this._defaultTokens]);
}
const toTokens = this._graph.get(fromLower)!;
if (!toTokens.includes(toLower)) {
toTokens.push(toLower);
}
return this;
}
public addBidirectional(tokenA: Address, tokenB: Address): TokenAdjacencyGraphBuilder {
return this.add(tokenA, tokenB).add(tokenB, tokenA);
}
public addCompleteSubgraph(tokens: Address[]): TokenAdjacencyGraphBuilder {
for (let i = 0; i < tokens.length; i++) {
for (let j = i + 1; j < tokens.length; j++) {
this.addBidirectional(tokens[i], tokens[j]);
}
}
return this;
}
public tap(cb: (graph: TokenAdjacencyGraphBuilder) => void): TokenAdjacencyGraphBuilder {
cb(this);
return this;
}
public build(): TokenAdjacencyGraph {
return new TokenAdjacencyGraph(this._graph, this._defaultTokens);
}
}

View File

@@ -0,0 +1,25 @@
import _ = require('lodash');
import { TokenAdjacencyGraph } from './market_operation_utils/types';
export class TokenAdjacencyGraphBuilder {
constructor(private readonly tokenAdjacency: TokenAdjacencyGraph) {}
public add(from: string, to: string | string[]): TokenAdjacencyGraphBuilder {
if (!this.tokenAdjacency[from]) {
this.tokenAdjacency[from] = [...this.tokenAdjacency.default];
}
this.tokenAdjacency[from] = [...(Array.isArray(to) ? to : [to]), ...this.tokenAdjacency[from]];
this.tokenAdjacency[from] = _.uniqBy(this.tokenAdjacency[from], a => a.toLowerCase());
return this;
}
public tap(cb: (builder: TokenAdjacencyGraphBuilder) => void): TokenAdjacencyGraphBuilder {
cb(this);
return this;
}
public build(): TokenAdjacencyGraph {
return this.tokenAdjacency;
}
}

View File

@@ -43,7 +43,6 @@ import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSamp
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 SynthetixSampler from '../test/generated-artifacts/SynthetixSampler.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';
@@ -51,7 +50,6 @@ import * as UniswapV2Sampler from '../test/generated-artifacts/UniswapV2Sampler.
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';
import * as WooPPSampler from '../test/generated-artifacts/WooPPSampler.json';
export const artifacts = {
ApproximateBuys: ApproximateBuys as ContractArtifact,
BalanceChecker: BalanceChecker as ContractArtifact,
@@ -78,14 +76,12 @@ export const artifacts = {
PlatypusSampler: PlatypusSampler as ContractArtifact,
SamplerUtils: SamplerUtils as ContractArtifact,
ShellSampler: ShellSampler as ContractArtifact,
SynthetixSampler: SynthetixSampler as ContractArtifact,
TwoHopSampler: TwoHopSampler as ContractArtifact,
UniswapSampler: UniswapSampler as ContractArtifact,
UniswapV2Sampler: UniswapV2Sampler as ContractArtifact,
UniswapV3Sampler: UniswapV3Sampler as ContractArtifact,
UtilitySampler: UtilitySampler as ContractArtifact,
VelodromeSampler: VelodromeSampler as ContractArtifact,
WooPPSampler: WooPPSampler as ContractArtifact,
IBalancer: IBalancer as ContractArtifact,
IBalancerV2Vault: IBalancerV2Vault as ContractArtifact,
IBancor: IBancor as ContractArtifact,

View File

@@ -43,7 +43,7 @@ blockchainTests.resets('BalanceChecker contract', env => {
const testResults = await contract.balances([owner, owner2], [makerToken.address, ETH_ADDRESS]).callAsync();
expect(testResults).to.eql([new BigNumber(100), new BigNumber(1000000000000000000000)]);
expect(testResults).to.eql([new BigNumber(100), new BigNumber(100000000000000000000)]);
});
it('it throws an error if the input arrays of different lengths', async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();

View File

@@ -13,8 +13,7 @@ import * as _ from 'lodash';
import { SignedOrder } from '../src/types';
import { DexOrderSampler, getSampleAmounts } from '../src/utils/market_operation_utils/sampler';
import { ERC20BridgeSource } from '../src/utils/market_operation_utils/types';
import { TokenAdjacencyGraphBuilder } from '../src/utils/token_adjacency_graph';
import { ERC20BridgeSource, TokenAdjacencyGraph } from '../src/utils/market_operation_utils/types';
import { MockSamplerContract } from './utils/mock_sampler_contract';
import { generatePseudoRandomSalt } from './utils/utils';
@@ -30,7 +29,7 @@ describe('DexSampler tests', () => {
const wethAddress = getContractAddressesForChainOrThrow(CHAIN_ID).etherToken;
const exchangeProxyAddress = getContractAddressesForChainOrThrow(CHAIN_ID).exchangeProxy;
const tokenAdjacencyGraph = new TokenAdjacencyGraphBuilder([wethAddress]).build();
const tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [wethAddress] };
describe('getSampleAmounts()', () => {
const FILL_AMOUNT = getRandomInteger(1, 1e18);

View File

@@ -15,7 +15,7 @@ import { Pool } from 'balancer-labs-sor-v1/dist/types';
import * as _ from 'lodash';
import * as TypeMoq from 'typemoq';
import { MarketOperation, QuoteRequestor, RfqRequestOpts, SignedNativeOrder, TokenAdjacencyGraph } from '../src';
import { MarketOperation, QuoteRequestor, RfqRequestOpts, SignedNativeOrder } from '../src';
import { Integrator } from '../src/types';
import { MarketOperationUtils } from '../src/utils/market_operation_utils/';
import {
@@ -24,7 +24,7 @@ import {
SOURCE_FLAGS,
ZERO_AMOUNT,
} from '../src/utils/market_operation_utils/constants';
import { AbstractPoolsCache } from '../src/utils/market_operation_utils/pools_cache';
import { PoolsCache } from '../src/utils/market_operation_utils/pools_cache';
import { DexOrderSampler } from '../src/utils/market_operation_utils/sampler';
import { BATCH_SOURCE_FILTERS } from '../src/utils/market_operation_utils/sampler_operations';
import { SourceFilters } from '../src/utils/market_operation_utils/source_filters';
@@ -39,6 +39,7 @@ import {
MarketSideLiquidity,
OptimizedMarketBridgeOrder,
OptimizerResultWithReport,
TokenAdjacencyGraph,
} from '../src/utils/market_operation_utils/types';
const MAKER_TOKEN = randomAddress();
@@ -56,7 +57,7 @@ const DEFAULT_EXCLUDED = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources
);
const BUY_SOURCES = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
const SELL_SOURCES = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
const TOKEN_ADJACENCY_GRAPH = TokenAdjacencyGraph.getEmptyGraph();
const TOKEN_ADJACENCY_GRAPH: TokenAdjacencyGraph = { default: [] };
const SIGNATURE = { v: 1, r: NULL_BYTES, s: NULL_BYTES, signatureType: SignatureType.EthSign };
const FOO_INTEGRATOR: Integrator = {
@@ -98,16 +99,16 @@ async function getMarketBuyOrdersAsync(
return utils.getOptimizerResultAsync(nativeOrders, makerAmount, MarketOperation.Buy, opts);
}
class MockPoolsCache extends AbstractPoolsCache {
class MockPoolsCache extends PoolsCache {
constructor(private readonly _handler: (takerToken: string, makerToken: string) => Pool[]) {
super(new Map());
super({});
}
protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<Pool[]> {
return this._handler(takerToken, makerToken);
}
}
// Return some pool so that sampling functions are called for Balancer and BalancerV2
// Return some pool so that sampling functions are called for Balancer, BalancerV2, and Cream
// tslint:disable:custom-no-magic-numbers
const mockPoolsCache = new MockPoolsCache((_takerToken: string, _makerToken: string) => {
return [
@@ -362,6 +363,7 @@ describe('MarketOperationUtils tests', () => {
[ERC20BridgeSource.MultiHop]: {},
[ERC20BridgeSource.Shell]: { poolAddress: randomAddress() },
[ERC20BridgeSource.Component]: { poolAddress: randomAddress() },
[ERC20BridgeSource.Cream]: { poolAddress: randomAddress() },
[ERC20BridgeSource.Dodo]: {},
[ERC20BridgeSource.DodoV2]: {},
[ERC20BridgeSource.CryptoCom]: { tokenAddressPath: [] },
@@ -401,6 +403,7 @@ describe('MarketOperationUtils tests', () => {
poolsCaches: {
[ERC20BridgeSource.BalancerV2]: mockPoolsCache,
[ERC20BridgeSource.Balancer]: mockPoolsCache,
[ERC20BridgeSource.Cream]: mockPoolsCache,
},
liquidityProviderRegistry: {},
chainId: CHAIN_ID,

View File

@@ -2,7 +2,12 @@ import { ChainId } from '@0x/contract-addresses';
import * as chai from 'chai';
import 'mocha';
import { BalancerPoolsCache, BalancerV2PoolsCache, PoolsCache } from '../src/utils/market_operation_utils/pools_cache';
import {
BalancerPoolsCache,
BalancerV2PoolsCache,
CreamPoolsCache,
PoolsCache,
} from '../src/utils/market_operation_utils/pools_cache';
import { chaiSetup } from './utils/chai_setup';
@@ -12,6 +17,9 @@ const expect = chai.expect;
const usdcAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
const daiAddress = '0x6b175474e89094c44da98b954eedeac495271d0f';
const wethAddress = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
const wbtcAddress = '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599';
const balAddress = '0xba100000625a3754423978a60c9317c58a424e3d';
const creamAddress = '0x2ba592f78db6436527729929aaf6c908497cb200';
const timeoutMs = 5000;
const poolKeys: string[] = ['id', 'balanceIn', 'balanceOut', 'weightIn', 'weightOut', 'swapFee'];
@@ -22,12 +30,12 @@ describe('Pools Caches for Balancer-based sampling', () => {
expect(pools.length).greaterThan(0, `Failed to find any pools for ${takerToken} and ${makerToken}`);
expect(pools[0]).not.undefined();
expect(Object.keys(pools[0])).to.include.members(poolKeys);
const cachedPoolIds = cache.getPoolAddressesForPair(takerToken, makerToken);
const cachedPoolIds = cache.getCachedPoolAddressesForPair(takerToken, makerToken);
expect(cachedPoolIds).to.deep.equal(pools.map(p => p.id));
}
describe('BalancerPoolsCache', () => {
const cache = BalancerPoolsCache.create(ChainId.Mainnet);
const cache = new BalancerPoolsCache();
it('fetches pools', async () => {
const pairs = [
[usdcAddress, daiAddress],
@@ -35,25 +43,36 @@ describe('Pools Caches for Balancer-based sampling', () => {
[daiAddress, wethAddress],
];
await Promise.all(
pairs.map(async ([takerToken, makerToken]) => fetchAndAssertPoolsAsync(cache, takerToken, makerToken)),
// tslint:disable-next-line:promise-function-async
pairs.map(([takerToken, makerToken]) => fetchAndAssertPoolsAsync(cache, takerToken, makerToken)),
);
});
});
describe('BalancerV2PoolsCache', () => {
it('fetches pools (Beethoven X - Fantom)', async () => {
const cache = BalancerV2PoolsCache.createBeethovenXPoolCache(ChainId.Fantom);
const wftmAddress = '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83';
const beetsAddress = '0xf24bcf4d1e507740041c9cfd2dddb29585adce1e';
const fantomWethAddress = '0x74b23882a30290451a17c44f4f05243b6b58c76d';
const cache = new BalancerV2PoolsCache(ChainId.Mainnet);
it('fetches pools', async () => {
const pairs = [
[wftmAddress, beetsAddress],
[wftmAddress, fantomWethAddress],
[wethAddress, wbtcAddress],
[wethAddress, balAddress],
];
await Promise.all(
pairs.map(async ([takerToken, makerToken]) => fetchAndAssertPoolsAsync(cache, takerToken, makerToken)),
// tslint:disable-next-line:promise-function-async
pairs.map(([takerToken, makerToken]) => fetchAndAssertPoolsAsync(cache, takerToken, makerToken)),
);
});
});
describe('CreamPoolsCache', () => {
const cache = new CreamPoolsCache();
it('fetches pools', async () => {
const pairs = [
[usdcAddress, creamAddress],
[creamAddress, wethAddress],
];
await Promise.all(
// tslint:disable-next-line:promise-function-async
pairs.map(([takerToken, makerToken]) => fetchAndAssertPoolsAsync(cache, takerToken, makerToken)),
);
});
});

View File

@@ -1,45 +0,0 @@
import * as chai from 'chai';
import 'mocha';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { ProtocolFeeUtils } from '../src';
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
const server = setupServer(
rest.get('https://mock-0x-gas-api.org/median', (_req, res, ctx) => {
return res(
ctx.json({
result: {
source: 'MEDIAN',
timestamp: 1659386474,
instant: 22000000000,
fast: 18848500000,
standard: 14765010000,
low: 13265000000,
},
}),
);
}),
);
describe('ProtocolFeeUtils', () => {
describe('getGasPriceEstimationOrThrowAsync', () => {
beforeEach(() => {
server.listen();
});
afterEach(() => {
server.close();
});
it('parses fast gas price response correctly', async () => {
const utils = ProtocolFeeUtils.getInstance(420000, 'https://mock-0x-gas-api.org/median');
const gasPrice = await utils.getGasPriceEstimationOrThrowAsync();
expect(gasPrice.toNumber()).to.eq(18848500000);
});
});
});

View File

@@ -1,108 +0,0 @@
import * as chai from 'chai';
import 'mocha';
import { TokenAdjacencyGraphBuilder } from '../src/utils/token_adjacency_graph';
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
describe('TokenAdjacencyGraphBuilder and TokenAdjacencyGraph', () => {
describe('constructor', () => {
it('sanitizes passed default tokens to lower case', async () => {
const graph = new TokenAdjacencyGraphBuilder(['DEFAULT_1', 'DEFAULT_2']).build();
expect(graph.getAdjacentTokens('random_token')).to.deep.eq(['default_1', 'default_2']);
});
});
describe('add', () => {
it('adds a new token path to the graph', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1', 'default_2']).add('token_a', 'token_b').build();
expect(graph.getAdjacentTokens('token_a')).to.deep.eq(['default_1', 'default_2', 'token_b']);
});
it('adds lower-cased token path to the graph', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1', 'default_2']).add('TOKEN_A', 'TOKEN_B').build();
expect(graph.getAdjacentTokens('token_a')).to.deep.eq(['default_1', 'default_2', 'token_b']);
});
it('ignores an existing to token', async () => {
const graph = new TokenAdjacencyGraphBuilder()
.add('token_a', 'token_b')
.add('token_a', 'token_b')
.build();
expect(graph.getAdjacentTokens('token_a')).to.deep.eq(['token_b']);
});
});
describe('addBidirectional', () => {
it('adds a bidirectional path to the graph', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1']).addBidirectional('token_a', 'token_b').build();
expect(graph.getAdjacentTokens('token_a')).to.deep.eq(['default_1', 'token_b']);
expect(graph.getAdjacentTokens('token_b')).to.deep.eq(['default_1', 'token_a']);
});
});
describe('addCompleteSubgraph', () => {
it('adds a complete subgraph to the graph', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1'])
.addCompleteSubgraph(['token_a', 'token_b', 'token_c', 'token_d'])
.build();
expect(graph.getAdjacentTokens('token_a')).to.deep.eq(['default_1', 'token_b', 'token_c', 'token_d']);
expect(graph.getAdjacentTokens('token_b')).to.deep.eq(['default_1', 'token_a', 'token_c', 'token_d']);
expect(graph.getAdjacentTokens('token_c')).to.deep.eq(['default_1', 'token_a', 'token_b', 'token_d']);
expect(graph.getAdjacentTokens('token_d')).to.deep.eq(['default_1', 'token_a', 'token_b', 'token_c']);
});
});
describe('tap', () => {
it('applies callback correctly', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1'])
.tap(g => {
g.add('token_a', 'token_b');
g.add('token_c', 'token_d');
})
.build();
expect(graph.getAdjacentTokens('token_a')).to.deep.eq(['default_1', 'token_b']);
expect(graph.getAdjacentTokens('token_c')).to.deep.eq(['default_1', 'token_d']);
});
});
describe('getIntermediateTokens', () => {
it('returns intermediate tokens without a duplicate ', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1'])
.add('token_a', 'token_b')
.add('token_c', 'token_b')
.build();
expect(graph.getIntermediateTokens('token_a', 'token_c')).to.deep.eq(['default_1', 'token_b']);
});
it('returns intermediate tokens after lower-casing taker and maker tokens', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1'])
.add('token_a', 'token_b')
.add('token_c', 'token_d')
.build();
expect(graph.getIntermediateTokens('TOKEN_a', 'token_C')).to.deep.eq(['default_1', 'token_b', 'token_d']);
});
it('returns intermediate tokens excluding taker token or maker token ', async () => {
const graph = new TokenAdjacencyGraphBuilder(['default_1'])
.addBidirectional('token_a', 'token_b')
.addBidirectional('token_b', 'token_c')
.addBidirectional('token_c', 'token_a')
.build();
expect(graph.getIntermediateTokens('token_a', 'token_c')).to.deep.eq(['default_1', 'token_b']);
});
});
});

View File

@@ -68,7 +68,7 @@ export const testHelpers = {
const { endpoint, mmApiKey, requestData, responseData, responseCode } = mockedResponse;
const requestHeaders = {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'Content-Type': 'application/json;charset=utf-8',
Authorization: `Bearer ${mmApiKey}`,
};
mockedAxios

View File

@@ -41,7 +41,6 @@ export * from '../test/generated-wrappers/native_order_sampler';
export * from '../test/generated-wrappers/platypus_sampler';
export * from '../test/generated-wrappers/sampler_utils';
export * from '../test/generated-wrappers/shell_sampler';
export * from '../test/generated-wrappers/synthetix_sampler';
export * from '../test/generated-wrappers/test_native_order_sampler';
export * from '../test/generated-wrappers/two_hop_sampler';
export * from '../test/generated-wrappers/uniswap_sampler';
@@ -49,4 +48,3 @@ export * from '../test/generated-wrappers/uniswap_v2_sampler';
export * from '../test/generated-wrappers/uniswap_v3_sampler';
export * from '../test/generated-wrappers/utility_sampler';
export * from '../test/generated-wrappers/velodrome_sampler';
export * from '../test/generated-wrappers/woo_p_p_sampler';

View File

@@ -44,14 +44,12 @@
"test/generated-artifacts/PlatypusSampler.json",
"test/generated-artifacts/SamplerUtils.json",
"test/generated-artifacts/ShellSampler.json",
"test/generated-artifacts/SynthetixSampler.json",
"test/generated-artifacts/TestNativeOrderSampler.json",
"test/generated-artifacts/TwoHopSampler.json",
"test/generated-artifacts/UniswapSampler.json",
"test/generated-artifacts/UniswapV2Sampler.json",
"test/generated-artifacts/UniswapV3Sampler.json",
"test/generated-artifacts/UtilitySampler.json",
"test/generated-artifacts/VelodromeSampler.json",
"test/generated-artifacts/WooPPSampler.json"
"test/generated-artifacts/VelodromeSampler.json"
]
}

View File

@@ -1,8 +1,6 @@
{
"extends": ["@0x/tslint-config"],
"rules": {
"array-type": false,
"custom-no-magic-numbers": false,
"max-file-line-count": false,
"binary-expression-operand-order": false
},

View File

@@ -1,117 +1,4 @@
[
{
"version": "6.23.2",
"changes": [
{
"note": "New FQT for arbitrum again",
"pr": 574
}
],
"timestamp": 1662559804
},
{
"version": "6.23.1",
"changes": [
{
"note": "New FQT for arbitrum",
"pr": 572
}
],
"timestamp": 1662147076
},
{
"version": "6.23.0",
"changes": [
{
"note": "Remove contract addresses that are no longer needed",
"pr": 564
},
{
"note": "Change WETH address in contract-addresses",
"pr": 571
}
],
"timestamp": 1662046042
},
{
"version": "6.22.0",
"changes": [
{
"note": "Arbitrum Rinkeby support",
"pr": 552
}
],
"timestamp": 1661462289
},
{
"version": "6.21.0",
"changes": [
{
"note": "Arbitrum addresses: need to be updated when deployed"
}
],
"timestamp": 1661459661
},
{
"version": "6.20.1",
"changes": [
{
"note": "Revert: Remove contract addresses that are no longer needed"
}
],
"timestamp": 1661145612
},
{
"version": "6.20.0",
"changes": [
{
"note": "Remove contract addresses that are no longer needed",
"pr": 548
}
]
},
{
"timestamp": 1660093941,
"version": "6.19.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "6.19.1",
"changes": [
{
"note": "Fix lowercase addresses",
"pr": 543
}
],
"timestamp": 1660073235
},
{
"version": "6.19.0",
"changes": [
{
"note": "Goerli and Mumbai updated verified contracts addresses",
"pr": 537
}
],
"timestamp": 1659750766
},
{
"version": "6.17.0",
"changes": [
{
"note": "Goerli and Mumbai"
},
{
"note": "Redeploy FQT on Mainnet and Optimism",
"pr": 530
}
],
"timestamp": 1658950329
},
{
"version": "6.16.0",
"changes": [

View File

@@ -5,52 +5,6 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v6.23.2 - _September 7, 2022_
* New FQT for arbitrum again (#574)
## v6.23.1 - _September 2, 2022_
* New FQT for arbitrum (#572)
## v6.23.0 - _September 1, 2022_
* Remove contract addresses that are no longer needed (#564)
* Change WETH address in contract-addresses (#571)
## v6.22.0 - _August 25, 2022_
* Arbitrum Rinkeby support (#552)
## v6.21.0 - _August 25, 2022_
* Arbitrum addresses: need to be updated when deployed
## v6.20.1 - _August 22, 2022_
* Revert: Remove contract addresses that are no longer needed
## v6.20.0 - _Invalid date_
* Remove contract addresses that are no longer needed (#548)
## v6.19.2 - _August 10, 2022_
* Dependencies updated
## v6.19.1 - _August 9, 2022_
* Fix lowercase addresses (#543)
## v6.19.0 - _August 6, 2022_
* Goerli and Mumbai updated verified contracts addresses (#537)
## v6.17.0 - _July 27, 2022_
* Goerli and Mumbai
* Redeploy FQT on Mainnet and Optimism (#530)
## v6.16.0 - _June 14, 2022_
* Redeploy FQT on Mainnet and Optimism

View File

@@ -1,13 +1,32 @@
{
"1": {
"exchangeV2": "0x080bf510fcbf18b91105470639e9561022937712",
"exchange": "0x61935cbdd02287b511119ddb11aeb42f1593b7ef",
"erc20Proxy": "0x95e6f48254609a6ee006f7d493c8e5fb97094cef",
"erc721Proxy": "0xefc70a1b18c432bdc64b596838b4d138f6bc6cad",
"forwarder": "0x6958f5e95332d93d21af0d7b9ca85b8212fee0a5",
"zrxToken": "0xe41d2489571d322189246dafa5ebde1f4699f498",
"etherToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"assetProxyOwner": "0xdffe798c7172dd6deb32baee68af322e8f495ce0",
"zeroExGovernor": "0x7d3455421bbc5ed534a83c88fd80387dc8271392",
"coordinatorRegistry": "0x45797531b873fd5e519477a070a955764c1a5b07",
"coordinator": "0x38a795580d0f687e399913a00ddef6a17612c722",
"multiAssetProxy": "0xef701d5389ae74503d633396c4d654eabedc9d78",
"staticCallProxy": "0x3517b88c19508c08650616019062b898ab65ed29",
"erc1155Proxy": "0x7eefbd48fd63d441ec7435d024ec7c5131019add",
"zrxVault": "0xba7f8b5fb1b19c1211c5d49550fcd149177a5eaf",
"staking": "0x2a17c35ff147b32f13f19f2e311446eeb02503f3",
"stakingProxy": "0xa26e80e7dea86279c6d778d702cc413e6cffa777",
"devUtils": "0x74134cf88b21383713e096a5ecf59e297dc7f547",
"erc20BridgeProxy": "0x8ed95d1746bf1e4dab58d8ed4724f1ef95b20db0",
"erc20BridgeSampler": "0xd8c38704c9937ea3312de29f824b4ad3450a5e61",
"chaiBridge": "0x77c31eba23043b9a72d13470f3a3a311344d7438",
"dydxBridge": "0x92af95e37afddac412e5688a9dcc1dd815d4ae53",
"godsUnchainedValidator": "0x09a379ef7218bcfd8913faa8b281ebc5a2e0bc04",
"broker": "0xd4690a51044db77d91d7aa8f7a3a5ad5da331af0",
"chainlinkStopLimit": "0xeb27220f95f364e1d9531992c48613f231839f53",
"maximumGasPrice": "0xe2bfd35306495d11e3c9db0d8de390cda24563cf",
"dexForwarderBridge": "0xc47b7094f378e54347e281aab170e8cca69d880a",
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x39dce47a67ad34344eab877eae3ef1fa2a1d50bb",
@@ -18,19 +37,38 @@
"wethTransformer": "0xb2bc06a4efb20fc6553a69dbfa49b7be938034a7",
"payTakerTransformer": "0x4638a7ebe75b911b995d0ec73a81e4f85f41f24e",
"affiliateFeeTransformer": "0xda6d9fc5998f550a094585cf9171f0e8ee3ac59f",
"fillQuoteTransformer": "0xd75a9019a2a1782ea670e4f4a55f04b43514ed53",
"fillQuoteTransformer": "0x26b2d9ea76f24206805d17565a5e0efcf787e0ae",
"positiveSlippageFeeTransformer": "0xa9416ce1dbde8d331210c07b5c253d94ee4cc3fd"
}
},
"3": {
"erc20Proxy": "0xf1ec7d0ba42f15fb5c9e3adbe86431973e44764c",
"erc721Proxy": "0x070efeb7e5ffa3d1a59d03a219539551ae60ba43",
"zrxToken": "0xff67881f8d12f372d91baae9752eb3631ff0ed00",
"etherToken": "0xc778417e063141139fce010982780140aa0cd5ab",
"exchangeV2": "0xbff9493f92a3df4b0429b6d00743b3cfb4c85831",
"exchange": "0x5d8c9ba74607d2cbc4176882a42d4ace891c1c00",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x53993733d41a88ae86f77a18a024e5548ee26579",
"forwarder": "0xd5abddda4ba89c0120edc0ca8a95ed1ad0bf9fc3",
"coordinatorRegistry": "0xf8becacec90bfc361c0a2c720839e08405a72f6d",
"coordinator": "0xc2e2f8faf4bf649123b6f94103646cb4a0331006",
"multiAssetProxy": "0x7b70a148e20b348c320208df84fdd642aab49fd0",
"staticCallProxy": "0xaa460127562482faa5df42f2c39a025cd4a1cc0a",
"erc1155Proxy": "0x7f10d80f2659aaae790ab03da12be11c4e6008c3",
"devUtils": "0xc812af3f3fbc62f76ea4262576ec0f49db8b7f1c",
"zrxVault": "0x38bbb9fb54a6b6d0376948bf3b2a7ed1e8aea6e8",
"staking": "0x4af649ffde640ceb34b1afaba3e0bb8e9698cb01",
"stakingProxy": "0x6acab4c9c4e3a0c78435fdb5ad1719c95460a668",
"erc20BridgeProxy": "0xb344afed348de15eb4a9e180205a2b0739628339",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0xd4690a51044db77d91d7aa8f7a3a5ad5da331af0",
"broker": "0x4022e3982f326455f0905de3dbc4449999baf2dc",
"chainlinkStopLimit": "0x67a094cf028221ffdd93fc658f963151d05e2a74",
"maximumGasPrice": "0x407b4128e9ecad8769b2332312a9f655cb9f5f3a",
"dexForwarderBridge": "0x3261ea1411a1a840aed708896f779e1b837c917e",
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x1c9a27658dd303a31205a3b245e8993b92d4d502",
@@ -46,14 +84,33 @@
}
},
"4": {
"exchangeV2": "0xbff9493f92a3df4b0429b6d00743b3cfb4c85831",
"exchange": "0xf8becacec90bfc361c0a2c720839e08405a72f6d",
"erc20Proxy": "0x070efeb7e5ffa3d1a59d03a219539551ae60ba43",
"erc721Proxy": "0x7f10d80f2659aaae790ab03da12be11c4e6008c3",
"zrxToken": "0x8080c7e4b81ecf23aa6f877cfbfd9b0c228c6ffa",
"etherToken": "0xc778417e063141139fce010982780140aa0cd5ab",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x3f46b98061a3e1e1f41dff296ec19402c298f8a9",
"forwarder": "0xe30f6166fe1cd5f0048abeed3d20360feb4a1fd8",
"coordinatorRegistry": "0xc2e2f8faf4bf649123b6f94103646cb4a0331006",
"coordinator": "0xf1ec7d0ba42f15fb5c9e3adbe86431973e44764c",
"multiAssetProxy": "0xb344afed348de15eb4a9e180205a2b0739628339",
"staticCallProxy": "0x7b70a148e20b348c320208df84fdd642aab49fd0",
"erc1155Proxy": "0xaa460127562482faa5df42f2c39a025cd4a1cc0a",
"devUtils": "0x46b5bc959e8a754c0256fff73bf34a52ad5cdfa9",
"zrxVault": "0x4af649ffde640ceb34b1afaba3e0bb8e9698cb01",
"staking": "0x6acab4c9c4e3a0c78435fdb5ad1719c95460a668",
"stakingProxy": "0x781ee6683595f823208be6540a279f940e6af196",
"erc20BridgeProxy": "0xa2aa4befed748fba27a3be7dfd2c4b2c6db1f49b",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0dd2d6cabbd8ae7d2fe6840fa597a44b1a7e4747",
"chainlinkStopLimit": "0x407b4128e9ecad8769b2332312a9f655cb9f5f3a",
"maximumGasPrice": "0x47697b44bd89051e93b4d5857ba8e024800a74ac",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x1c9a27658dd303a31205a3b245e8993b92d4d502",
@@ -68,38 +125,34 @@
"positiveSlippageFeeTransformer": "0x0000000000000000000000000000000000000000"
}
},
"5": {
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0xf289f8a9d26f9a32ecc8602e92e634d71a91d490",
"exchangeProxy": "0xf91bb752490473b8342a3e964e855b9f9a2a668e",
"exchangeProxyTransformerDeployer": "0x7b4f0063cc0097c19c6b8cc74ecaf630621e2be6",
"exchangeProxyFlashWallet": "0xf15469c80a1965f5f90be5651fcb6c6f3392b2a1",
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
"zrxTreasury": "0x0000000000000000000000000000000000000000",
"transformers": {
"wethTransformer": "0x5e485f1ab8aa2a71d533f2bc15af64dd10fa44e9",
"payTakerTransformer": "0x0c59ced2ffce5fceb40f665def2146f76c576f34",
"affiliateFeeTransformer": "0x6f4d30df1ecaed54239af95efa2964f9252fd0a3",
"fillQuoteTransformer": "0x841b18c263a290c41ac41b6afbf4c1d31b0c6b36",
"positiveSlippageFeeTransformer": "0x5d6ab5729a08775c69035730bcfbad65759c4f4d"
}
},
"42": {
"erc20Proxy": "0xaa460127562482faa5df42f2c39a025cd4a1cc0a",
"erc721Proxy": "0x7b70a148e20b348c320208df84fdd642aab49fd0",
"zrxToken": "0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa",
"etherToken": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
"exchangeV2": "0x30589010550762d2f0d06f650d8e8b6ade6dbf4b",
"exchange": "0xf1ec7d0ba42f15fb5c9e3adbe86431973e44764c",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x6ff734d96104965c9c1b0108f83abc46e6e501df",
"forwarder": "0x0f64646a5154ae5e58b6dd87ede7b04f508d76f8",
"coordinatorRegistry": "0x070efeb7e5ffa3d1a59d03a219539551ae60ba43",
"coordinator": "0x7f10d80f2659aaae790ab03da12be11c4e6008c3",
"multiAssetProxy": "0x58a01e826e60731247e7de8b446ed4c8535a099c",
"staticCallProxy": "0xa2aa4befed748fba27a3be7dfd2c4b2c6db1f49b",
"erc1155Proxy": "0xb344afed348de15eb4a9e180205a2b0739628339",
"devUtils": "0xc67ae71928568a180b3aad1339dedcf3076876fe",
"zrxVault": "0x781ee6683595f823208be6540a279f940e6af196",
"staking": "0x73ea24041e03a012c51a45c307e0ba376af0238c",
"stakingProxy": "0xe94cb304b3f515be7c95fedcfa249a84995fd748",
"erc20BridgeProxy": "0x3577552c1fb7a44ad76beeb7ab53251668a21f8d",
"erc20BridgeSampler": "0x298a99d3a2b891df04019425542897ac1a867d9d",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0xc213707de0454008758071c2edc1365621b8a5c5",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0xcdeb6d90ee7c96b4c713f7bb4f8604981f7ebe9d",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x67a094cf028221ffdd93fc658f963151d05e2a74",
"dexForwarderBridge": "0x985d1a95c6a86a3bf85c4d425af984abceaf01de",
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x1b62de2dbb5e7aa519e9c442721ecef75702807f",
@@ -115,14 +168,33 @@
}
},
"56": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0xccc9769c1a58766e79423a34b2cc5052d65c1983",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x8224aa8fe5c9f07d5a59c735386ff6cc6aaeb568",
@@ -133,19 +205,38 @@
"wethTransformer": "0xac3d95668c092e895cd83a9cbafe9c7d9906471f",
"payTakerTransformer": "0x4f5e8ca2cadecd4a467ae441e4b03de4278a4574",
"affiliateFeeTransformer": "0x1be34ab9b2acb5c4ddd89454bdce637967e65230",
"fillQuoteTransformer": "0xbd7fd6e116fc8589bb658fba3a2cc6273050bcf2",
"fillQuoteTransformer": "0x0b72d55485e8d877f73cc8b14ea3e010b3e804fd",
"positiveSlippageFeeTransformer": "0x7f5c79ad1788573b1145f4651a248523c54f5d1f"
}
},
"1337": {
"erc20Proxy": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c",
"etherToken": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"zrxVault": "0xf23276778860e420acfc18ebeebf7e829b06965c",
"staking": "0x8a063452f7df2614db1bca3a85ef35da40cf0835",
"stakingProxy": "0x59adefa01843c627ba5d6aa350292b4b7ccae67a",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x0000000000000000000000000000000000000000",
"exchangeProxy": "0x5315e44798395d4a952530d131249fe00f554565",
"exchangeProxyTransformerDeployer": "0x5409ed021d9299bf6814279a6a1411a7e866a631",
@@ -161,14 +252,33 @@
}
},
"137": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x4d3e56c56a55d23fc7aa9a9ffad61631cf7d1ae6",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0xe6d9207df11c55bce2f7a189ae95e3222d5484d3",
@@ -179,42 +289,80 @@
"wethTransformer": "0xe309d011cc6f189a3e8dcba85922715a019fed38",
"payTakerTransformer": "0x5ba7b9be86cda01cfbf56e0fb97184783be9dda1",
"affiliateFeeTransformer": "0xbed27284b42e5684e987169cf1da09c5d6c49fa8",
"fillQuoteTransformer": "0x01c082e47c8dc6dedd01e3fcb07bfd3eb72e044d",
"fillQuoteTransformer": "0xd4a518760030dae1adbde9496f8a3b478e83932a",
"positiveSlippageFeeTransformer": "0x4cd8f1c0df4d40fcc1e073845d5f6f4ed5cc8dab"
}
},
"80001": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x9c3c9283d3e44854697cd22d3faa240cfb032889",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x30186b2e187aeddabf019089f9375a8dc53138e4",
"exchangeProxy": "0xf471d32cb40837bf24529fcf17418fc1a4807626",
"exchangeProxyTransformerDeployer": "0x05481589f447a0767def2b0ed98a04ea5f5eba50",
"exchangeProxyFlashWallet": "0x64254cf2f3abd765bee46f8445b76e2bb0af5a2c",
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x4cf19577bcb5e784f315e952f97a6dc247f03140",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0xa8220408bcb5b327875fd82145d379a83dfd7d61",
"exchangeProxyFlashWallet": "0xdb6f1920a889355780af7570773609bd8cb1f498",
"exchangeProxyLiquidityProviderSandbox": "0xe6f76f5090f8d64015113841a0c9bc5d14755d6f",
"zrxTreasury": "0x0000000000000000000000000000000000000000",
"transformers": {
"wethTransformer": "0x445af2e5791cc9a72f81c49a3dc90cf3b03d2a62",
"payTakerTransformer": "0xe3e8652fb306873f9dc87222423ffd51b967f014",
"affiliateFeeTransformer": "0xbd901aff2ce18355537594a17ebb0a38ca44d8b6",
"fillQuoteTransformer": "0xbfac39aea3c0a6222266cef674ec39c3b5387852",
"positiveSlippageFeeTransformer": "0x33ab86b46d84d30538a9b35c7ece4d5673caa778"
"wethTransformer": "0x44a65ee6b33f70eda7b854abe8d81e925984c932",
"payTakerTransformer": "0x2f4868ed9cae9a4cdba063818dce19f411be4e75",
"affiliateFeeTransformer": "0x843c0ac5b1b373be51800c8f1caffe54cc29dd22",
"fillQuoteTransformer": "0x750cb81ee6d64e29e1e358ba155925000bf044d4",
"positiveSlippageFeeTransformer": "0x30aebc4c68effa70e21612b39b94299a8778d0cb"
}
},
"43114": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0xca7bab1b2d1ec7d81710b7f9e2ab4e6788930588",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0xa60b57833dce6260f4f2411c811755dd980bc0a7",
@@ -225,19 +373,38 @@
"wethTransformer": "0x9b8b52391071d71cd4ad1e61d7f273268fa34c6c",
"payTakerTransformer": "0x898c6fde239d646c73f0a57e3570b6f86a3d62a3",
"affiliateFeeTransformer": "0x34617b855411e52fbc05899435f44cbd0503022c",
"fillQuoteTransformer": "0xcee9118bc14e1fe740c54c754b901629b322ee4f",
"fillQuoteTransformer": "0xb6c9c52ce7094fc96d8bd5d3ecd0c6feeafe3457",
"positiveSlippageFeeTransformer": "0x470ba89da18a6db6e8a0567b3c9214b960861857"
}
},
"250": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0xf760c5b88d970d6f97e64e264dac5a3767dafd74",
"exchangeProxy": "0xdef189deaef76e379df891899eb5a00a94cbc250",
"exchangeProxyTransformerDeployer": "0x47f01db18a38261e4cb153bae6db7d3743acb33c",
@@ -248,19 +415,38 @@
"wethTransformer": "0x9b6aa8f26a92108e7d1f66373d757bb955112703",
"payTakerTransformer": "0x32df54951d33d7460e15fa59b1fcc262183ce4c2",
"affiliateFeeTransformer": "0x67efa679a4b56c38713d478e649c88247f4f8e88",
"fillQuoteTransformer": "0xe40f81ef6e9c95ba04c659b8d032eab73152aafd",
"fillQuoteTransformer": "0x641efe8a57ad39353fe22f77d211ef6b17b0590b",
"positiveSlippageFeeTransformer": "0xe87d69b285005cc82b53b844322652c49ed64600"
}
},
"42220": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x471ece3750da237f93b8e339c536989b8978a438",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x92115010fd9b170d4918b102efc86b1b7bebdc7f",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x1fe80d5ad9464dba2d60b88e449305f184823f8a",
@@ -276,14 +462,33 @@
}
},
"10": {
"erc20Proxy": "0x0000000000000000000000000000000000000000",
"erc721Proxy": "0x0000000000000000000000000000000000000000",
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x4200000000000000000000000000000000000006",
"exchangeV2": "0x0000000000000000000000000000000000000000",
"exchange": "0x0000000000000000000000000000000000000000",
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"forwarder": "0x0000000000000000000000000000000000000000",
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
"coordinator": "0x0000000000000000000000000000000000000000",
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
"staticCallProxy": "0x0000000000000000000000000000000000000000",
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
"devUtils": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"chaiBridge": "0x0000000000000000000000000000000000000000",
"dydxBridge": "0x0000000000000000000000000000000000000000",
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
"broker": "0x0000000000000000000000000000000000000000",
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x6d506b2847df0c6f04d2628da1adaf4d8fb2e81b",
"exchangeProxy": "0xdef1abe32c034e558cdd535791643c58a13acc10",
"exchangeProxyTransformerDeployer": "0x3a539ed6bd42de8fbaf3899fb490c792e153d647",
@@ -294,54 +499,8 @@
"wethTransformer": "0x02ce7af6520e2862f961f5d7eda746642865179c",
"payTakerTransformer": "0x085d10a34f14f6a631ea8ff7d016782ee3ffaa11",
"affiliateFeeTransformer": "0x55cf1d7535250db75bf0190493f55781ee583553",
"fillQuoteTransformer": "0x96499c097efc56ba5cf6b2a474392db17790ce96",
"fillQuoteTransformer": "0xfae0ce3841afbf5625a15f0c73e03ba6660e575f",
"positiveSlippageFeeTransformer": "0xb11e14565dfbeb702dea9bc0cb47f1a8b32f4783"
}
},
"421611": {
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x4200000000000000000000000000000000000006",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0xf5e66206eb523988eae22dd7d4e06e36999fef94",
"exchangeProxy": "0x2c1994270ae589deae7b4bb6c2446c57d40b99d4",
"exchangeProxyTransformerDeployer": "0x42b43abe1358a7b2c00f8eb5b2668f821ee8edbf",
"exchangeProxyFlashWallet": "0xc1831049d451b69a9dccc391f8285eb83c94c940",
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
"zrxTreasury": "0x0000000000000000000000000000000000000000",
"transformers": {
"wethTransformer": "0x7c0ef1020f9ee63bcf8248006174b9cbaa29af5a",
"payTakerTransformer": "0xb5c5ebd57ccf14480e30ce85f891f894cedbc694",
"affiliateFeeTransformer": "0xfa3d8ca1c877185af1ce2ec558e586e12cdbc50c",
"fillQuoteTransformer": "0xd6ddb08beb4c48e35352ee4df5ebc028e72f3c81",
"positiveSlippageFeeTransformer": "0x8830f7c5925b129efcc7831397f30c1c02953bac"
}
},
"42161": {
"zrxToken": "0x0000000000000000000000000000000000000000",
"etherToken": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
"zrxVault": "0x0000000000000000000000000000000000000000",
"staking": "0x0000000000000000000000000000000000000000",
"stakingProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
"exchangeProxyGovernor": "0x1fe80d5ad9464dba2d60b88e449305f184823f8a",
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
"exchangeProxyTransformerDeployer": "0x29f80c1f685e19ae1807063eda432f431ac623d0",
"exchangeProxyFlashWallet": "0xdb6f1920a889355780af7570773609bd8cb1f498",
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
"zrxTreasury": "0x0000000000000000000000000000000000000000",
"transformers": {
"wethTransformer": "0x10e968968f49dd66a5efeebbb2edcb9c49c4fc49",
"payTakerTransformer": "0xae3e8cf7bf340d7084f312dfae2aa8b01c885b02",
"affiliateFeeTransformer": "0x05a24978471869327904ea13da3c4322128e2aaa",
"fillQuoteTransformer": "0x542c7dfc7959d8d03c5b738478213885ab3f214e",
"positiveSlippageFeeTransformer": "0xd56b9c014b45ed95e2a048a0c28121db30265f13"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contract-addresses",
"version": "6.23.2",
"version": "6.16.0",
"engines": {
"node": ">=6.12"
},
@@ -12,8 +12,6 @@
"scripts": {
"build": "yarn tsc -b",
"build:ci": "yarn build",
"test": "mocha --require source-map-support/register 'lib/test/**/*_test.js' --timeout 10000 --bail --exit",
"test:circleci": "yarn test",
"clean": "shx rm -rf lib",
"publish:private": "yarn build && gitpkg publish"
},
@@ -30,11 +28,7 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/packages/contract-addresses",
"devDependencies": {
"@types/mocha": "^5.2.7",
"chai": "^4.0.1",
"ethereumjs-util": "^7.1.5",
"gitpkg": "https://github.com/0xProject/gitpkg.git",
"mocha": "^6.2.0",
"shx": "^0.2.2",
"typescript": "4.6.3"
},

View File

@@ -1,14 +1,33 @@
import addresses from '../addresses.json';
export interface ContractAddresses {
erc20Proxy: string;
erc721Proxy: string;
zrxToken: string;
etherToken: string;
exchangeV2: string;
exchange: string;
assetProxyOwner: string;
zeroExGovernor: string;
forwarder: string;
coordinatorRegistry: string;
coordinator: string;
multiAssetProxy: string;
staticCallProxy: string;
erc1155Proxy: string;
devUtils: string;
zrxVault: string;
staking: string;
stakingProxy: string;
erc20BridgeProxy: string;
erc20BridgeSampler: string;
chaiBridge: string;
dydxBridge: string;
godsUnchainedValidator: string;
broker: string;
chainlinkStopLimit: string;
maximumGasPrice: string;
dexForwarderBridge: string;
exchangeProxyGovernor: string;
exchangeProxy: string;
exchangeProxyTransformerDeployer: string;
@@ -28,7 +47,6 @@ export enum ChainId {
Mainnet = 1,
Ropsten = 3,
Rinkeby = 4,
Goerli = 5,
Kovan = 42,
Ganache = 1337,
BSC = 56,
@@ -38,8 +56,6 @@ export enum ChainId {
Fantom = 250,
Celo = 42220,
Optimism = 10,
Arbitrum = 42161,
ArbitrumRinkeby = 421611,
}
/**

Some files were not shown because too many files have changed in this diff Show More