Compare commits

...

65 Commits

Author SHA1 Message Date
Github Actions
23788b41d5 Publish
- @0x/asset-swapper@16.57.3
2022-05-10 01:41:10 +00:00
Github Actions
ccf999a495 Updated CHANGELOGS & MD docs 2022-05-10 01:41:06 +00:00
Kyu
aa1016ee5f Do not initialize BalancerV2SwapInfoCache on unsupported chains [TKR-365] (#472)
* Do not initialize BalancerV2SwapInfoCache on unsupported chains
* Update CHANGELOG.json
2022-05-09 18:21:04 -07:00
Github Actions
423ef57344 Publish
- @0x/asset-swapper@16.57.2
2022-05-02 21:22:37 +00:00
Github Actions
c18149e82f Updated CHANGELOGS & MD docs 2022-05-02 21:22:33 +00:00
Jorge Pérez
d14aebf724 Fix the filter for considered sources on indicative sells for Quote Report (#466) 2022-05-02 15:45:15 -05:00
Kyu
ba719a9631 Add cvxfxs-fxs curve pool on Ethereum mainnet (#465)
* Add cvxfxs-fxs curve pool on Ethereum mainnet

* Update CHANGELOG.json

* Fix an existing formatting issue

* Adjust gasSchedule and merge the change under 16.57.1
2022-04-27 17:07:36 -07:00
eobbad
d36034d958 chore/ANY-QUICK on polygon MAG-MIM on avax (#464)
* Added ANY/QUICK pair on Polygon

* Updated changelog.json

* Update CHANGELOG.json
2022-04-26 10:55:03 -04:00
Github Actions
7750c57620 Publish
- @0x/contracts-erc20@3.3.29
 - @0x/contracts-test-utils@5.4.20
 - @0x/contracts-treasury@1.4.12
 - @0x/contracts-utils@4.8.10
 - @0x/contracts-zero-ex@0.32.0
 - @0x/asset-swapper@16.57.0
 - @0x/contract-addresses@6.13.0
 - @0x/contract-wrappers@13.20.1
 - @0x/migrations@8.1.18
 - @0x/protocol-utils@11.12.0
2022-04-22 07:05:10 +00:00
Github Actions
4d027e11d1 Updated CHANGELOGS & MD docs 2022-04-22 07:05:06 +00:00
Lawrence Forman
470e9a4697 AS: Balancer V2 batchSwap (#462)
* Draft. PoC pseudo code showing general idea for resuing SOR path creation logic and adding multihop support.

* Add actual Balancer SDK function calls.

* Update to handle buys.

* Correct taker>maker for buy.

* Draft. PoC pseudo code showing general idea for resuing SOR path creation logic and adding multihop support.

* make it build

* rebase

* add BalancerV2Batch protocol

* add BalancerV2Batch protocol

* get balancer v2 multihop working

* fix BalancerV2Batch for sells (buys still iffy)

* fix buys, appease linter and prettier

* remove unused RPC URL from balancer sdk construction

* update changelogs

* clean up comments
add event loop yield in `BalancerV2SwapInfoCache.loadTopPools()`

* add negative result check on balancerv2batch swap output

* compiler hack

* reintroduce CompilerHack

* delete unused multibridge sampler

* remove compilerhack

* reintroduce compilerhack

* try to fix CI compile errors

* plz work

* plz work

* pretty plz work

* yay it works, also address feedback

* appease linter

* deploy new FQTs

Co-authored-by: johngrantuk <johngrantuk@googlemail.com>
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2022-04-22 02:43:41 -04:00
Github Actions
7c51412e2f Publish
- @0x/asset-swapper@16.56.0
2022-04-21 21:16:27 +00:00
Github Actions
b3d1f3cd10 Updated CHANGELOGS & MD docs 2022-04-21 21:16:23 +00:00
mzhu25
389bb77439 Add estimatedGas to ExtendedQuoteReport (#463) 2022-04-21 13:52:13 -07:00
Github Actions
4327885a00 Publish
- @0x/asset-swapper@16.55.0
2022-04-07 16:07:52 +00:00
Github Actions
0aef0afbbb Updated CHANGELOGS & MD docs 2022-04-07 16:07:49 +00:00
Lawrence Forman
fa4c3a4f5f fix quote consumer RFQ VIP code path not checking if transfromERC20 is required (#461)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2022-04-07 11:58:07 -04:00
Github Actions
1d7c527c5c Publish
- @0x/asset-swapper@16.54.0
2022-04-06 03:26:22 +00:00
Github Actions
cbe3135e4b Updated CHANGELOGS & MD docs 2022-04-06 03:26:18 +00:00
Lawrence Forman
955ad49711 add real VIP support for eligible RFQT swaps (#458)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2022-04-05 23:00:12 -04:00
Github Actions
8d6f6e76e0 Publish
- @0x/contracts-erc20@3.3.28
 - @0x/contracts-test-utils@5.4.19
 - @0x/contracts-treasury@1.4.11
 - @0x/contracts-utils@4.8.9
 - @0x/contracts-zero-ex@0.31.2
 - @0x/asset-swapper@16.53.0
 - @0x/contract-addresses@6.12.1
 - @0x/contract-artifacts@3.18.0
 - @0x/contract-wrappers@13.20.0
 - @0x/migrations@8.1.17
 - @0x/protocol-utils@1.11.2
2022-03-31 15:09:24 +00:00
Github Actions
9337115650 Updated CHANGELOGS & MD docs 2022-03-31 15:09:21 +00:00
Kim Persson
fa45a44fe4 fix: use Node 16 for publish GH action (#457) 2022-03-31 16:47:02 +02:00
Kim Persson
c9c7ac8559 feat: add block number to quote report data [TKR-314] (#448)
* feat: add blockNumber to MarketSideLiquidity response

* fix: return block number back in swap quote response

* chore: add asset-swapper changelog entry
2022-03-31 15:42:34 +02:00
Kim Persson
c881723578 feat: use neon-router in CI tests (#453)
* fix: initially skip all tests that don't work with the Rust router

* fix: enable rust router for CircleCI tests

* fix: handle invalid output sampels & enable numSamples tests

* chore: add comments about disabled tests

* chore: add asset-swapper changelog entry
2022-03-31 14:32:59 +02:00
Kim Persson
c9c30d3a76 chore: bump ts version to solve type issue with ethereumjs (#455) 2022-03-31 13:55:17 +02:00
Noah Khamliche
73dfdb5b69 fixed gas estimation and removed hint from intermediate tokens 2022-03-21 14:51:23 -04:00
Noah Khamliche
e638268f94 updated routing 2022-03-21 14:51:23 -04:00
Noah Khamliche
0bfd765481 updating changelog 2022-03-21 14:51:23 -04:00
Noah Khamliche
1f12893735 fixing routing 2022-03-21 14:51:23 -04:00
Noah Khamliche
dd3d9337c4 Added Stargate curve pool 2022-03-21 14:51:23 -04:00
Lawrence Forman
904214f4a8 ugprade tools deps and regenerate wrappers (#449)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2022-03-16 12:14:31 -04:00
Noah Khamliche
64c090c4b4 removed local bignumber resolution 2022-03-10 21:22:28 -05:00
Noah Khamliche
e24474f152 lint and prettier 2022-03-10 21:22:28 -05:00
Noah Khamliche
29fa408256 final nitpicks 2022-03-10 21:22:28 -05:00
Noah Khamliche
1b94cc68af fixed gas schedule 2022-03-10 21:22:28 -05:00
Noah Khamliche
f5b4bb3035 removed low liquidity pools, and fixed some routing 2022-03-10 21:22:28 -05:00
Noah Khamliche
afd880f28c poolAddress -> NULL_ADDRESS for consitent types 2022-03-10 21:22:28 -05:00
Noah Khamliche
cd14cdd168 fixed lint 2022-03-10 21:22:28 -05:00
Noah Khamliche
c8ff53a75f fixed mobius common argument abstraction 2022-03-10 21:22:28 -05:00
Noah Khamliche
6d08add20b minimized reused code for mobius pairs 2022-03-10 21:22:28 -05:00
Noah Khamliche
29f9c725e3 bump changelog to version after feat/BTRFLYCurve 2022-03-10 21:22:28 -05:00
Noah Khamliche
a83453f07f prettier and lint 2022-03-10 21:22:28 -05:00
Noah Khamliche
ae365ce92c finished off mobius money pairs 2022-03-10 21:22:28 -05:00
Noah Khamliche
77a592e891 added mobius config for celo and some inital test pools 2022-03-10 21:22:28 -05:00
Github Actions
9a1df67d6b Publish
- @0x/asset-swapper@16.51.0
2022-03-10 04:58:07 +00:00
Github Actions
4b91411faf Updated CHANGELOGS & MD docs 2022-03-10 04:58:04 +00:00
Jacob Evans
622a542d57 feat: Curve YFI-ETH (#444)
* feat: Curve YFI-ETH

* CHANGELOG
2022-03-10 14:36:59 +10:00
Github Actions
cba53a9a50 Publish
- @0x/asset-swapper@16.50.3
2022-03-09 14:59:25 +00:00
Github Actions
e186f27f63 Updated CHANGELOGS & MD docs 2022-03-09 14:59:22 +00:00
Kim Persson
4cd767ecb8 feat: VIP routing in the router, don't create fallback orders for native [TKR-243] (#440)
* feat: calculate all routes and VIP only routes in a single router call

* fix: Try to disable using fallback orders for quotes with native orders

* fix: create VIP sources set once per routing call

* chore: use private publish version of neon-router to test

* chore(lint): comment out unused fn _addOptionalFallbackAsync

* chore: update to latest private publish of neon-router

* refactor: fix router metrics beforeTimeMs naming

* feat: don't recompute isVip for ever sample of a source

* chore: update neon-router to real published version

* fix: merge conflict resolution issue

* chore: add asset-swapper changelog entry
2022-03-09 15:39:47 +01:00
Shawn
f6e85aedf1 Fix/routing glue optimization (#439)
* fix: only create fills if using js router, remove `unoptimizedPath`

* minor optimizations

* remove the cap of route output in buys

* change PR number

* fix: Update Ropsten UniswapV3 Router address (#441)

* fix: Update Ropsten UniswapV3 Router address

* Update CHANGELOG

* Updated CHANGELOGS & MD docs

* Publish

 - @0x/asset-swapper@16.50.2

* change PR number

Co-authored-by: Kim Persson <kimpersson88@gmail.com>
Co-authored-by: Jacob Evans <jacob@dekz.net>
Co-authored-by: Github Actions <github-actions@github.com>
2022-03-08 16:26:22 -08:00
Github Actions
b3ee294ba5 Publish
- @0x/asset-swapper@16.50.2
2022-03-07 01:37:11 +00:00
Github Actions
1c242def93 Updated CHANGELOGS & MD docs 2022-03-07 01:37:07 +00:00
Jacob Evans
f0fe6f2f69 fix: Update Ropsten UniswapV3 Router address (#441)
* fix: Update Ropsten UniswapV3 Router address

* Update CHANGELOG
2022-03-07 11:18:25 +10:00
Github Actions
f86d555e49 Publish
- @0x/asset-swapper@16.50.1
2022-03-03 13:04:04 +00:00
Github Actions
b0f2c40463 Updated CHANGELOGS & MD docs 2022-03-03 13:04:00 +00:00
Kim Persson
87be6fbb8a fix: lower UniswapV3Sampler quote gas allowance to 700k (#438)
* fix: lower UniswapV3Sampler quote gas allowance to 700k

* chore: add asset-swapper changelog entry
2022-03-03 13:45:20 +01:00
Noah Khamliche
9141a9d2c8 feat: BTRFLY/WETH factory pool (#437)
* added curve support for BTRFLY/WETH factory pool

* prettier and lint

* remove timestamp

* fixed gas schedule for btrflyweth pool

* chore: update Node16 (#384)


* Node 16

* update yarn.lock

* Update ganache-cli and merkle-patricia-tree

* [TKR-275] Add Geist on Fantom (#398)

* Add Geist on Fantom

* nvm there is not subgraph for it

* finish giest utils

* Address pr comments

* lowercase gtoken addresses

* return undefined instead of error for unsupported pairs

* another lower case

* Update fantom fillQuoteTransformer address

* more const clean up

* feat: Improve Uniswap V3 gas schedule redux (#424)

* Revert "fix: Revert Improve Uniswap V3 gas schedule (#397) (#419)"

This reverts commit df0e0866e4.

* fix: UniswapV3Sampler return token amounts as the last value in return tuple

* fix: bump Uniswap V3 quote max gas because QuoterV2 is more expensive

* fix: don't try to rout 0 sellAmount/buyAmount quotes

* fix: Linting issue

* fix: use median gas usage instead of mean in UniV3 gas schedule

* chore: add asset-swapper changelog entry

* fix: remove contract-addresses changelog empty row failing linting

* Updated CHANGELOGS & MD docs

* Publish

 - @0x/contracts-erc20@3.3.27
 - @0x/contracts-test-utils@5.4.18
 - @0x/contracts-treasury@1.4.10
 - @0x/contracts-utils@4.8.8
 - @0x/contracts-zero-ex@0.31.1
 - @0x/asset-swapper@16.50.0
 - @0x/contract-addresses@6.12.0
 - @0x/contract-wrappers@13.19.1
 - @0x/migrations@8.1.16
 - @0x/protocol-utils@1.11.1

* Add v4 NFT Audits (#435)

* prettier and lint

Co-authored-by: Jacob Evans <jacob@dekz.net>
Co-authored-by: Cece Z <cece@0xproject.com>
Co-authored-by: Kim Persson <kimpers@users.noreply.github.com>
Co-authored-by: Github Actions <github-actions@github.com>
Co-authored-by: Jessica Lin <jlin2700@gmail.com>
2022-03-02 21:18:40 -05:00
Jessica Lin
7f75de347e Add v4 NFT Audits (#435) 2022-03-02 10:46:00 -08:00
Github Actions
329f7761c3 Publish
- @0x/contracts-erc20@3.3.27
 - @0x/contracts-test-utils@5.4.18
 - @0x/contracts-treasury@1.4.10
 - @0x/contracts-utils@4.8.8
 - @0x/contracts-zero-ex@0.31.1
 - @0x/asset-swapper@16.50.0
 - @0x/contract-addresses@6.12.0
 - @0x/contract-wrappers@13.19.1
 - @0x/migrations@8.1.16
 - @0x/protocol-utils@1.11.1
2022-03-02 12:55:58 +00:00
Github Actions
0d8e83cd75 Updated CHANGELOGS & MD docs 2022-03-02 12:55:55 +00:00
Kim Persson
e5d60b8077 feat: Improve Uniswap V3 gas schedule redux (#424)
* Revert "fix: Revert Improve Uniswap V3 gas schedule (#397) (#419)"

This reverts commit df0e0866e4.

* fix: UniswapV3Sampler return token amounts as the last value in return tuple

* fix: bump Uniswap V3 quote max gas because QuoterV2 is more expensive

* fix: don't try to rout 0 sellAmount/buyAmount quotes

* fix: Linting issue

* fix: use median gas usage instead of mean in UniV3 gas schedule

* chore: add asset-swapper changelog entry

* fix: remove contract-addresses changelog empty row failing linting
2022-03-02 13:36:12 +01:00
Cece Z
ae2fe55efa [TKR-275] Add Geist on Fantom (#398)
* Add Geist on Fantom

* nvm there is not subgraph for it

* finish giest utils

* Address pr comments

* lowercase gtoken addresses

* return undefined instead of error for unsupported pairs

* another lower case

* Update fantom fillQuoteTransformer address

* more const clean up
2022-03-02 01:34:30 -05:00
Jacob Evans
6073607d3e chore: update Node16 (#384)
* Node 16

* update yarn.lock

* Update ganache-cli and merkle-patricia-tree
2022-03-02 11:50:35 +10:00
106 changed files with 3785 additions and 2502 deletions

View File

@@ -4,7 +4,7 @@ jobs:
build:
resource_class: xlarge
docker:
- image: node:12
- image: node:16
environment:
NODE_OPTIONS: '--max-old-space-size=16384'
working_directory: ~/repo
@@ -19,7 +19,6 @@ jobs:
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
- setup_remote_docker
- run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci
- run: yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts
- save_cache:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -31,7 +30,7 @@ jobs:
test-exchange-ganache:
resource_class: medium+
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
@@ -41,7 +40,7 @@ jobs:
test-integrations-ganache:
resource_class: medium+
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
@@ -51,7 +50,7 @@ jobs:
test-contracts-staking-ganache:
resource_class: medium+
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
@@ -61,7 +60,7 @@ jobs:
test-contracts-extra-ganache:
resource_class: medium+
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
@@ -71,7 +70,7 @@ jobs:
test-contracts-rest-ganache:
resource_class: medium+
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
@@ -83,7 +82,7 @@ jobs:
environment:
NODE_OPTIONS: '--max-old-space-size=6442'
docker:
- image: node:12
- image: node:16
- image: 0xorg/verdaccio
working_directory: ~/repo
steps:
@@ -97,7 +96,7 @@ jobs:
path: ~/.npm/_logs
test-doc-generation:
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:
@@ -108,8 +107,10 @@ jobs:
no_output_timeout: 1200
test-rest:
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
environment:
RUST_ROUTER: "true"
steps:
- restore_cache:
keys:
@@ -136,7 +137,7 @@ jobs:
resource_class: large
working_directory: ~/repo
docker:
- image: node:12
- image: node:16
steps:
- restore_cache:
keys:
@@ -147,7 +148,7 @@ jobs:
- run: yarn diff_md_docs:ci
submit-coverage:
docker:
- image: node:12
- image: node:16
working_directory: ~/repo
steps:
- restore_cache:

View File

@@ -28,7 +28,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-node@v1
with:
node-version: 10
node-version: 16
- uses: actions/setup-python@v2
- name: 'configure git'
run: |

View File

@@ -1,4 +1,31 @@
[
{
"timestamp": 1650611093,
"version": "3.3.29",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1648739346,
"version": "3.3.28",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1646225739,
"version": "3.3.27",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1645569128,
"version": "3.3.26",

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.3.29 - _April 22, 2022_
* Dependencies updated
## v3.3.28 - _March 31, 2022_
* Dependencies updated
## v3.3.27 - _March 2, 2022_
* Dependencies updated
## v3.3.26 - _February 22, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc20",
"version": "3.3.26",
"version": "3.3.29",
"engines": {
"node": ">=6.12"
},
@@ -51,18 +51,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.7.2",
"@0x/contracts-gen": "^2.0.43",
"@0x/contracts-test-utils": "^5.4.17",
"@0x/contracts-utils": "^4.8.7",
"@0x/dev-utils": "^4.2.11",
"@0x/sol-compiler": "^4.7.8",
"@0x/abi-gen": "^5.8.0",
"@0x/contracts-gen": "^2.0.46",
"@0x/contracts-test-utils": "^5.4.20",
"@0x/contracts-utils": "^4.8.10",
"@0x/dev-utils": "^4.2.14",
"@0x/sol-compiler": "^4.8.1",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"@0x/types": "^3.3.6",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -70,7 +70,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.6.0",
"ethereum-types": "^3.7.0",
"lodash": "^4.17.11",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
@@ -79,10 +79,10 @@
"solhint": "^1.4.1",
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^6.4.5",
"@0x/base-contract": "^6.5.0",
"ethers": "~4.0.4"
},
"publishConfig": {

View File

@@ -1,4 +1,31 @@
[
{
"timestamp": 1650611093,
"version": "5.4.20",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1648739346,
"version": "5.4.19",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1646225739,
"version": "5.4.18",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1645569128,
"version": "5.4.17",

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v5.4.20 - _April 22, 2022_
* Dependencies updated
## v5.4.19 - _March 31, 2022_
* Dependencies updated
## v5.4.18 - _March 2, 2022_
* Dependencies updated
## v5.4.17 - _February 22, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-test-utils",
"version": "5.4.17",
"version": "5.4.20",
"engines": {
"node": ">=6.12"
},
@@ -34,28 +34,28 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
"devDependencies": {
"@0x/sol-compiler": "^4.7.8",
"@0x/sol-compiler": "^4.8.1",
"@0x/tslint-config": "^4.1.4",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"tslint": "5.11.0",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"dependencies": {
"@0x/assert": "^3.0.31",
"@0x/base-contract": "^6.4.5",
"@0x/contract-addresses": "^6.11.0",
"@0x/dev-utils": "^4.2.11",
"@0x/json-schemas": "^6.4.1",
"@0x/assert": "^3.0.34",
"@0x/base-contract": "^6.5.0",
"@0x/contract-addresses": "^6.13.0",
"@0x/dev-utils": "^4.2.14",
"@0x/json-schemas": "^6.4.4",
"@0x/order-utils": "^10.4.28",
"@0x/sol-coverage": "^4.0.42",
"@0x/sol-profiler": "^4.1.32",
"@0x/sol-trace": "^3.0.42",
"@0x/subproviders": "^6.6.2",
"@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"@0x/sol-coverage": "^4.0.45",
"@0x/sol-profiler": "^4.1.35",
"@0x/sol-trace": "^3.0.45",
"@0x/subproviders": "^6.6.5",
"@0x/types": "^3.3.6",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"@types/bn.js": "^4.11.0",
"@types/js-combinatorics": "^0.5.29",
"@types/lodash": "4.14.104",
@@ -67,7 +67,7 @@
"chai-bignumber": "^3.0.0",
"decimal.js": "^10.2.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.6.0",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10",
"ethers": "~4.0.4",
"js-combinatorics": "^0.5.3",

View File

@@ -1,4 +1,31 @@
[
{
"timestamp": 1650611093,
"version": "1.4.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1648739346,
"version": "1.4.11",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1646225739,
"version": "1.4.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1645569128,
"version": "1.4.9",

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.4.12 - _April 22, 2022_
* Dependencies updated
## v1.4.11 - _March 31, 2022_
* Dependencies updated
## v1.4.10 - _March 2, 2022_
* Dependencies updated
## v1.4.9 - _February 22, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-treasury",
"version": "1.4.9",
"version": "1.4.12",
"engines": {
"node": ">=6.12"
},
@@ -46,14 +46,14 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
"devDependencies": {
"@0x/abi-gen": "^5.7.2",
"@0x/contract-addresses": "^6.11.0",
"@0x/abi-gen": "^5.8.0",
"@0x/contract-addresses": "^6.13.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-erc20": "^3.3.26",
"@0x/contracts-gen": "^2.0.43",
"@0x/contracts-erc20": "^3.3.29",
"@0x/contracts-gen": "^2.0.46",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-test-utils": "^5.4.17",
"@0x/sol-compiler": "^4.7.8",
"@0x/contracts-test-utils": "^5.4.20",
"@0x/sol-compiler": "^4.8.1",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@types/isomorphic-fetch": "^0.0.35",
@@ -69,17 +69,17 @@
"solhint": "^1.4.1",
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^6.4.5",
"@0x/protocol-utils": "^1.11.0",
"@0x/subproviders": "^6.6.2",
"@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"ethereum-types": "^3.6.0",
"@0x/base-contract": "^6.5.0",
"@0x/protocol-utils": "^11.12.0",
"@0x/subproviders": "^6.6.5",
"@0x/types": "^3.3.6",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10"
},
"publishConfig": {

View File

@@ -1,4 +1,31 @@
[
{
"timestamp": 1650611093,
"version": "4.8.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1648739346,
"version": "4.8.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1646225739,
"version": "4.8.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1645569128,
"version": "4.8.7",

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.8.10 - _April 22, 2022_
* Dependencies updated
## v4.8.9 - _March 31, 2022_
* Dependencies updated
## v4.8.8 - _March 2, 2022_
* Dependencies updated
## v4.8.7 - _February 22, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-utils",
"version": "4.8.7",
"version": "4.8.10",
"engines": {
"node": ">=6.12"
},
@@ -50,15 +50,15 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
"devDependencies": {
"@0x/abi-gen": "^5.7.2",
"@0x/contracts-gen": "^2.0.43",
"@0x/contracts-test-utils": "^5.4.17",
"@0x/dev-utils": "^4.2.11",
"@0x/abi-gen": "^5.8.0",
"@0x/contracts-gen": "^2.0.46",
"@0x/contracts-test-utils": "^5.4.20",
"@0x/dev-utils": "^4.2.14",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.8",
"@0x/sol-compiler": "^4.8.1",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.4",
"@0x/web3-wrapper": "^7.6.2",
"@0x/types": "^3.3.6",
"@0x/web3-wrapper": "^7.6.5",
"@types/bn.js": "^4.11.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -76,14 +76,14 @@
"solhint": "^1.4.1",
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^6.4.5",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/base-contract": "^6.5.0",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"bn.js": "^4.11.8",
"ethereum-types": "^3.6.0"
"ethereum-types": "^3.7.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,32 @@
[
{
"version": "0.32.0",
"changes": [
{
"note": "Add support for `BalancerV2Batch` fills in FQT",
"pr": 462
}
],
"timestamp": 1650611093
},
{
"timestamp": 1648739346,
"version": "0.31.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1646225739,
"version": "0.31.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.31.0",
"changes": [

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.32.0 - _April 22, 2022_
* Add support for `BalancerV2Batch` fills in FQT (#462)
## v0.31.2 - _March 31, 2022_
* Dependencies updated
## v0.31.1 - _March 2, 2022_
* Dependencies updated
## v0.31.0 - _February 22, 2022_
* Add ERC721OrdersFeature, ERC1155OrdersFeature, and ERC165Feature (#429)

View File

@@ -25,6 +25,7 @@ import "./BridgeProtocols.sol";
import "./mixins/MixinAaveV2.sol";
import "./mixins/MixinBalancer.sol";
import "./mixins/MixinBalancerV2.sol";
import "./mixins/MixinBalancerV2Batch.sol";
import "./mixins/MixinBancor.sol";
import "./mixins/MixinCoFiX.sol";
import "./mixins/MixinCompound.sol";
@@ -52,6 +53,7 @@ contract BridgeAdapter is
MixinAaveV2,
MixinBalancer,
MixinBalancerV2,
MixinBalancerV2Batch,
MixinBancor,
MixinCoFiX,
MixinCompound,
@@ -159,6 +161,11 @@ contract BridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.BALANCERV2BATCH) {
boughtAmount = _tradeBalancerV2Batch(
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.KYBER) {
boughtAmount = _tradeKyber(
sellToken,

View File

@@ -27,29 +27,30 @@ library BridgeProtocols {
// A incrementally increasing, append-only list of protocol IDs.
// We don't use an enum so solidity doesn't throw when we pass in a
// new protocol ID that hasn't been rolled up yet.
uint128 internal constant UNKNOWN = 0;
uint128 internal constant CURVE = 1;
uint128 internal constant UNISWAPV2 = 2;
uint128 internal constant UNISWAP = 3;
uint128 internal constant BALANCER = 4;
uint128 internal constant KYBER = 5;
uint128 internal constant MOONISWAP = 6;
uint128 internal constant MSTABLE = 7;
uint128 internal constant OASIS = 8;
uint128 internal constant SHELL = 9;
uint128 internal constant DODO = 10;
uint128 internal constant DODOV2 = 11;
uint128 internal constant CRYPTOCOM = 12;
uint128 internal constant BANCOR = 13;
uint128 internal constant COFIX = 14;
uint128 internal constant NERVE = 15;
uint128 internal constant MAKERPSM = 16;
uint128 internal constant BALANCERV2 = 17;
uint128 internal constant UNISWAPV3 = 18;
uint128 internal constant KYBERDMM = 19;
uint128 internal constant CURVEV2 = 20;
uint128 internal constant LIDO = 21;
uint128 internal constant CLIPPER = 22; // Not used: Clipper is now using PLP interface
uint128 internal constant AAVEV2 = 23;
uint128 internal constant COMPOUND = 24;
uint128 internal constant UNKNOWN = 0;
uint128 internal constant CURVE = 1;
uint128 internal constant UNISWAPV2 = 2;
uint128 internal constant UNISWAP = 3;
uint128 internal constant BALANCER = 4;
uint128 internal constant KYBER = 5;
uint128 internal constant MOONISWAP = 6;
uint128 internal constant MSTABLE = 7;
uint128 internal constant OASIS = 8;
uint128 internal constant SHELL = 9;
uint128 internal constant DODO = 10;
uint128 internal constant DODOV2 = 11;
uint128 internal constant CRYPTOCOM = 12;
uint128 internal constant BANCOR = 13;
uint128 internal constant COFIX = 14;
uint128 internal constant NERVE = 15;
uint128 internal constant MAKERPSM = 16;
uint128 internal constant BALANCERV2 = 17;
uint128 internal constant UNISWAPV3 = 18;
uint128 internal constant KYBERDMM = 19;
uint128 internal constant CURVEV2 = 20;
uint128 internal constant LIDO = 21;
uint128 internal constant CLIPPER = 22; // Not used: Clipper is now using PLP interface
uint128 internal constant AAVEV2 = 23;
uint128 internal constant COMPOUND = 24;
uint128 internal constant BALANCERV2BATCH = 25;
}

View File

@@ -0,0 +1,107 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
interface IBalancerV2BatchSwapVault {
enum SwapKind { GIVEN_IN, GIVEN_OUT }
struct BatchSwapStep {
bytes32 poolId;
uint256 assetInIndex;
uint256 assetOutIndex;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
function batchSwap(
SwapKind kind,
BatchSwapStep[] calldata swaps,
IERC20TokenV06[] calldata assets,
FundManagement calldata funds,
int256[] calldata limits,
uint256 deadline
) external returns (int256[] memory amounts);
}
contract MixinBalancerV2Batch {
using LibERC20TokenV06 for IERC20TokenV06;
struct BalancerV2BatchBridgeData {
IBalancerV2BatchSwapVault vault;
IBalancerV2BatchSwapVault.BatchSwapStep[] swapSteps;
IERC20TokenV06[] assets;
}
function _tradeBalancerV2Batch(
uint256 sellAmount,
bytes memory bridgeData
)
internal
returns (uint256 boughtAmount)
{
// Decode the bridge data.
(
IBalancerV2BatchSwapVault vault,
IBalancerV2BatchSwapVault.BatchSwapStep[] memory swapSteps,
address[] memory assets_
) = abi.decode(bridgeData, (IBalancerV2BatchSwapVault, IBalancerV2BatchSwapVault.BatchSwapStep[], address[]));
IERC20TokenV06[] memory assets;
assembly { assets := assets_ }
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
assets[0].approveIfBelow(address(vault), sellAmount);
swapSteps[0].amount = sellAmount;
int256[] memory limits = new int256[](assets.length);
for (uint256 i = 0; i < limits.length; ++i) {
limits[i] = type(int256).max;
}
int256[] memory amounts = vault.batchSwap(
IBalancerV2BatchSwapVault.SwapKind.GIVEN_IN,
swapSteps,
assets,
IBalancerV2BatchSwapVault.FundManagement({
sender: address(this),
fromInternalBalance: false,
recipient: payable(address(this)),
toInternalBalance: false
}),
limits,
block.timestamp + 1
);
require(amounts[amounts.length - 1] <= 0, 'Unexpected BalancerV2Batch output');
return uint256(amounts[amounts.length - 1] * -1);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-zero-ex",
"version": "0.31.0",
"version": "0.32.0",
"engines": {
"node": ">=6.12"
},
@@ -43,7 +43,7 @@
"config": {
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
},
"repository": {
"type": "git",
@@ -55,14 +55,14 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
"devDependencies": {
"@0x/abi-gen": "^5.7.2",
"@0x/contract-addresses": "^6.11.0",
"@0x/contracts-erc20": "^3.3.26",
"@0x/contracts-gen": "^2.0.43",
"@0x/contracts-test-utils": "^5.4.17",
"@0x/dev-utils": "^4.2.11",
"@0x/abi-gen": "^5.8.0",
"@0x/contract-addresses": "^6.13.0",
"@0x/contracts-erc20": "^3.3.29",
"@0x/contracts-gen": "^2.0.46",
"@0x/contracts-test-utils": "^5.4.20",
"@0x/dev-utils": "^4.2.14",
"@0x/order-utils": "^10.4.28",
"@0x/sol-compiler": "^4.7.8",
"@0x/sol-compiler": "^4.8.1",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@types/isomorphic-fetch": "^0.0.35",
@@ -79,17 +79,17 @@
"truffle": "^5.0.32",
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"dependencies": {
"@0x/base-contract": "^6.4.5",
"@0x/protocol-utils": "^1.11.0",
"@0x/subproviders": "^6.6.2",
"@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"ethereum-types": "^3.6.0",
"@0x/base-contract": "^6.5.0",
"@0x/protocol-utils": "^11.12.0",
"@0x/subproviders": "^6.6.5",
"@0x/types": "^3.3.6",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10",
"ethers": "~4.0.4"
},

View File

@@ -101,6 +101,7 @@ import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransa
import * as MixinAaveV2 from '../test/generated-artifacts/MixinAaveV2.json';
import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json';
import * as MixinBalancerV2Batch from '../test/generated-artifacts/MixinBalancerV2Batch.json';
import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
import * as MixinCompound from '../test/generated-artifacts/MixinCompound.json';
@@ -313,6 +314,7 @@ export const artifacts = {
MixinAaveV2: MixinAaveV2 as ContractArtifact,
MixinBalancer: MixinBalancer as ContractArtifact,
MixinBalancerV2: MixinBalancerV2 as ContractArtifact,
MixinBalancerV2Batch: MixinBalancerV2Batch as ContractArtifact,
MixinBancor: MixinBancor as ContractArtifact,
MixinCoFiX: MixinCoFiX as ContractArtifact,
MixinCompound: MixinCompound as ContractArtifact,

View File

@@ -99,6 +99,7 @@ export * from '../test/generated-wrappers/meta_transactions_feature';
export * from '../test/generated-wrappers/mixin_aave_v2';
export * from '../test/generated-wrappers/mixin_balancer';
export * from '../test/generated-wrappers/mixin_balancer_v2';
export * from '../test/generated-wrappers/mixin_balancer_v2_batch';
export * from '../test/generated-wrappers/mixin_bancor';
export * from '../test/generated-wrappers/mixin_co_fi_x';
export * from '../test/generated-wrappers/mixin_compound';

View File

@@ -132,6 +132,7 @@
"test/generated-artifacts/MixinAaveV2.json",
"test/generated-artifacts/MixinBalancer.json",
"test/generated-artifacts/MixinBalancerV2.json",
"test/generated-artifacts/MixinBalancerV2Batch.json",
"test/generated-artifacts/MixinBancor.json",
"test/generated-artifacts/MixinCoFiX.json",
"test/generated-artifacts/MixinCompound.json",

View File

@@ -4,23 +4,28 @@ Audits
Below are links to our third-party audit reports.
+------------------+---------------------------------------------------------------------------------------------------------------+
| **Release** | **Reports** |
+------------------+---------------------------------------------------------------------------------------------------------------+
| Exchange V4 | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__ |
+------------------+---------------------------------------------------------------------------------------------------------------+
| Exchange V3 | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`_ |
| | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__ |
| | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__ |
+------------------+---------------------------------------------------------------------------------------------------------------+
| Exchange V2.1 | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_ |
| | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_ |
+------------------+---------------------------------------------------------------------------------------------------------------+
| MultiAssetProxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__ |
+------------------+---------------------------------------------------------------------------------------------------------------+
| ERC1155Proxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__ |
+------------------+---------------------------------------------------------------------------------------------------------------+
| StaticCallProxy | * No third-party audit. |
+------------------+---------------------------------------------------------------------------------------------------------------+
| ERC20BridgeProxy | * No third-party audit. |
+------------------+---------------------------------------------------------------------------------------------------------------+
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| **Release** | **Reports** |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| ERC721OrdersFeature | * `ABDK Consulting <https://s3.us-east-2.amazonaws.com/zeips.0x.org/audits/abdk-consulting/ABDK_0x_Solidity_v_1_0.pdf>`__ |
| | |
| | |
| ERC1155OrdersFeature | |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| Exchange V4 | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__ |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| Exchange V3 | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`__ |
| | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__ |
| | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__ |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| Exchange V2.1 | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_ |
| | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_ |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| MultiAssetProxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__ |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| ERC1155Proxy | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__ |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| StaticCallProxy | * No third-party audit. |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+
| ERC20BridgeProxy | * No third-party audit. |
+----------------------+---------------------------------------------------------------------------------------------------------------------------+

View File

@@ -60,21 +60,22 @@
"ignoreDependencyVersionsForPackage": "contract-wrappers"
},
"devDependencies": {
"@0x/monorepo-scripts": "^3.2.1",
"@0x-lerna-fork/lerna": "3.16.10",
"@0x/monorepo-scripts": "^3.2.4",
"@0xproject/npm-cli-login": "^0.0.11",
"async-child-process": "^1.1.1",
"coveralls": "^3.0.0",
"ganache-cli": "6.8.0-istanbul.0",
"ganache-cli": "6.12.2",
"lcov-result-merger": "^3.0.0",
"lerna": "^3.0.0-beta.25",
"npm-run-all": "^4.1.2",
"prettier": "1.19.1",
"source-map-support": "^0.5.6",
"typescript": "4.2.2",
"typescript": "4.6.3",
"wsrun": "^5.2.4"
},
"resolutions": {
"merkle-patricia-tree": "^2.3.2"
"merkle-patricia-tree": "3.0.0",
"**/bignumber.js": "^9.0.2"
}
}

View File

@@ -1,4 +1,166 @@
[
{
"version": "16.57.3",
"changes": [
{
"note": "Fix a runtime error related to BalancerV2SwapInfoCache",
"pr": 472
}
],
"timestamp": 1652146864
},
{
"version": "16.57.2",
"changes": [
{
"note": "Fix missing AMM quotes on indicative Quote Reports",
"pr": 466
}
],
"timestamp": 1651526551
},
{
"version": "16.57.1",
"changes": [
{
"note": "Added QUICK/ANY pair on Polygon",
"pr": 464
},
{
"note": "Added cvxFXS/FXS curve pool on mainnet",
"pr": 465
}
]
},
{
"version": "16.57.0",
"changes": [
{
"note": "Add BalancerV2 batch swap support",
"pr": 462
}
],
"timestamp": 1650611093
},
{
"version": "16.56.0",
"changes": [
{
"note": "Add estimatedGas to ExtendedQuoteReport",
"pr": 463
}
],
"timestamp": 1650575781
},
{
"version": "16.55.0",
"changes": [
{
"note": "Fix fillRfqOrder VIP being used for swaps that need transformERC20",
"pr": 461
}
],
"timestamp": 1649347667
},
{
"version": "16.54.0",
"changes": [
{
"note": "Add true VIP support for eligible RFQt swaps",
"pr": 458
}
],
"timestamp": 1649215576
},
{
"version": "16.53.0",
"changes": [
{
"note": "Adds support for STG/USDC pool on Curve Mainnet",
"pr": 451
},
{
"note": "Use neon-router in asset-swapper tests",
"pr": 453
},
{
"note": "Add sampler blocknumber to quote report data",
"pr": 448
}
],
"timestamp": 1648739346
},
{
"version": "16.52.0",
"changes": [
{
"note": "Adds support for mobius money on celo",
"pr": 423
}
]
},
{
"version": "16.51.0",
"changes": [
{
"note": "Added `Curve` `YFI-ETH` pool",
"pr": 444
}
],
"timestamp": 1646888282
},
{
"version": "16.50.3",
"changes": [
{
"note": "Routing glue optimization",
"pr": 439
},
{
"note": "Move VIP source routing into neon-router & disable fallback orders for native/plp",
"pr": 440
}
],
"timestamp": 1646837959
},
{
"version": "16.50.2",
"changes": [
{
"note": "Update `Uniswap_V3` address on `Ropsten`",
"pr": 441
}
],
"timestamp": 1646617024
},
{
"version": "16.50.1",
"changes": [
{
"note": "Add BTRFLY/WETH Curve pool on mainnet",
"pr": 437
},
{
"note": "Lower Uniswap V3 Sampler gas allowance",
"pr": 438
}
],
"timestamp": 1646312638
},
{
"version": "16.50.0",
"changes": [
{
"note": "Adding support for Geist on `Fantom`",
"pr": 398
},
{
"note": "Improve Uniswap V3 gas schedule",
"pr": 424
}
],
"timestamp": 1646225739
},
{
"version": "16.49.9",
"changes": [

View File

@@ -5,6 +5,68 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v16.57.3 - _May 10, 2022_
* Fix a runtime error related to BalancerV2SwapInfoCache (#472)
## v16.57.2 - _May 2, 2022_
* Fix missing AMM quotes on indicative Quote Reports (#466)
## v16.57.1 - _Invalid date_
* Added QUICK/ANY pair on Polygon (#464)
* Added cvxFXS/FXS curve pool on mainnet (#465)
## v16.57.0 - _April 22, 2022_
* Add BalancerV2 batch swap support (#462)
## v16.56.0 - _April 21, 2022_
* Add estimatedGas to ExtendedQuoteReport (#463)
## v16.55.0 - _April 7, 2022_
* Fix fillRfqOrder VIP being used for swaps that need transformERC20 (#461)
## v16.54.0 - _April 6, 2022_
* Add true VIP support for eligible RFQt swaps (#458)
## v16.53.0 - _March 31, 2022_
* Adds support for STG/USDC pool on Curve Mainnet (#451)
* Use neon-router in asset-swapper tests (#453)
* Add sampler blocknumber to quote report data (#448)
## v16.52.0 - _Invalid date_
* Adds support for mobius money on celo (#423)
## v16.51.0 - _March 10, 2022_
* Added `Curve` `YFI-ETH` pool (#444)
## v16.50.3 - _March 9, 2022_
* Routing glue optimization (#439)
* Move VIP source routing into neon-router & disable fallback orders for native/plp (#440)
## v16.50.2 - _March 7, 2022_
* Update `Uniswap_V3` address on `Ropsten` (#441)
## v16.50.1 - _March 3, 2022_
* Add BTRFLY/WETH Curve pool on mainnet (#437)
* Lower Uniswap V3 Sampler gas allowance (#438)
## v16.50.0 - _March 2, 2022_
* Adding support for Geist on `Fantom` (#398)
* Improve Uniswap V3 gas schedule (#424)
## v16.49.9 - _February 24, 2022_
* Fix native order scaling & filter out 1 wei quotes (#430)

View File

@@ -6,7 +6,7 @@
"shouldSaveStandardInput": true,
"compilerSettings": {
"evmVersion": "istanbul",
"optimizer": { "enabled": true, "runs": 200, "details": { "yul": true, "deduplicate": true } },
"optimizer": { "enabled": true, "runs": 200, "details": { "yul": false, "deduplicate": true } },
"outputSelection": {
"*": {
"*": [

View File

@@ -0,0 +1,105 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IBalancerV2Vault.sol";
import "./BalancerV2Common.sol";
contract BalancerV2BatchSampler is BalancerV2Common {
// Replaces amount for first step with each takerTokenAmount and calls queryBatchSwap using supplied steps
/// @dev Sample sell quotes from Balancer V2 supporting multihops.
/// @param swapSteps Array of swap steps (can be >= 1).
/// @param swapAssets Array of token address for swaps.
/// @param takerTokenAmounts Taker token sell amount for each sample.
function sampleMultihopSellsFromBalancerV2(
IBalancerV2Vault vault,
IBalancerV2Vault.BatchSwapStep[] memory swapSteps,
address[] memory swapAssets,
uint256[] memory takerTokenAmounts
)
public
returns (uint256[] memory makerTokenAmounts)
{
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
IBalancerV2Vault.FundManagement memory swapFunds =
_createSwapFunds();
for (uint256 i = 0; i < numSamples; i++) {
swapSteps[0].amount = takerTokenAmounts[i];
try
// For sells we specify the takerToken which is what the vault will receive from the trade
vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_IN, swapSteps, swapAssets, swapFunds)
// amounts represent pool balance deltas from the swap (incoming balance, outgoing balance)
returns (int256[] memory amounts) {
// Outgoing balance is negative so we need to flip the sign
// Note - queryBatchSwap will return a delta for each token in the assets array and last asset should be tokenOut
int256 amountOutFromPool = amounts[amounts.length - 1] * -1;
if (amountOutFromPool <= 0) {
break;
}
makerTokenAmounts[i] = uint256(amountOutFromPool);
} catch {
// Swallow failures, leaving all results as zero.
break;
}
}
}
// Replaces amount for first step with each makerTokenAmount and calls queryBatchSwap using supplied steps
/// @dev Sample buy quotes from Balancer V2 supporting multihops.
/// @param swapSteps Array of swap steps (can be >= 1).
/// @param swapAssets Array of token address for swaps.
/// @param makerTokenAmounts Maker token buy amount for each sample.
function sampleMultihopBuysFromBalancerV2(
IBalancerV2Vault vault,
IBalancerV2Vault.BatchSwapStep[] memory swapSteps,
address[] memory swapAssets,
uint256[] memory makerTokenAmounts
)
public
returns (uint256[] memory takerTokenAmounts)
{
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
IBalancerV2Vault.FundManagement memory swapFunds =
_createSwapFunds();
for (uint256 i = 0; i < numSamples; i++) {
swapSteps[0].amount = makerTokenAmounts[i];
try
// Uses GIVEN_OUT type for Buy
vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_OUT, swapSteps, swapAssets, swapFunds)
// amounts represent pool balance deltas from the swap (incoming balance, outgoing balance)
returns (int256[] memory amounts) {
int256 amountIntoPool = amounts[0];
if (amountIntoPool <= 0) {
break;
}
takerTokenAmounts[i] = uint256(amountIntoPool);
} catch {
// Swallow failures, leaving all results as zero.
break;
}
}
}
}

View File

@@ -0,0 +1,41 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IBalancerV2Vault.sol";
contract BalancerV2Common {
function _createSwapFunds()
internal
view
returns (IBalancerV2Vault.FundManagement memory)
{
return
IBalancerV2Vault.FundManagement({
sender: address(this),
fromInternalBalance: false,
recipient: payable(address(this)),
toInternalBalance: false
});
}
}

View File

@@ -21,44 +21,11 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerUtils.sol";
import "./interfaces/IBalancerV2Vault.sol";
import "./BalancerV2Common.sol";
/// @dev Minimal Balancer V2 Vault interface
/// for documentation refer to https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/vault/interfaces/IVault.sol
interface IBalancerV2Vault {
enum SwapKind { GIVEN_IN, GIVEN_OUT }
struct BatchSwapStep {
bytes32 poolId;
uint256 assetInIndex;
uint256 assetOutIndex;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
function queryBatchSwap(
SwapKind kind,
BatchSwapStep[] calldata swaps,
IAsset[] calldata assets,
FundManagement calldata funds
) external returns (int256[] memory assetDeltas);
}
interface IAsset {
// solhint-disable-previous-line no-empty-blocks
}
contract BalancerV2Sampler is SamplerUtils {
struct BalancerV2PoolInfo {
bytes32 poolId;
address vault;
}
contract BalancerV2Sampler is SamplerUtils, BalancerV2Common {
/// @dev Sample sell quotes from Balancer V2.
/// @param poolInfo Struct with pool related data
@@ -68,7 +35,7 @@ contract BalancerV2Sampler is SamplerUtils {
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromBalancerV2(
BalancerV2PoolInfo memory poolInfo,
IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
@@ -78,9 +45,9 @@ contract BalancerV2Sampler is SamplerUtils {
{
_assertValidPair(makerToken, takerToken);
IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault);
IAsset[] memory swapAssets = new IAsset[](2);
swapAssets[0] = IAsset(takerToken);
swapAssets[1] = IAsset(makerToken);
address[] memory swapAssets = new address[](2);
swapAssets[0] = takerToken;
swapAssets[1] = makerToken;
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
@@ -97,7 +64,7 @@ contract BalancerV2Sampler is SamplerUtils {
// amounts represent pool balance deltas from the swap (incoming balance, outgoing balance)
returns (int256[] memory amounts) {
// Outgoing balance is negative so we need to flip the sign
int256 amountOutFromPool = amounts[1] * -1;
int256 amountOutFromPool = amounts[amounts.length - 1] * -1;
if (amountOutFromPool <= 0) {
break;
}
@@ -117,7 +84,7 @@ contract BalancerV2Sampler is SamplerUtils {
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromBalancerV2(
BalancerV2PoolInfo memory poolInfo,
IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
@@ -127,9 +94,9 @@ contract BalancerV2Sampler is SamplerUtils {
{
_assertValidPair(makerToken, takerToken);
IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault);
IAsset[] memory swapAssets = new IAsset[](2);
swapAssets[0] = IAsset(takerToken);
swapAssets[1] = IAsset(makerToken);
address[] memory swapAssets = new address[](2);
swapAssets[0] = takerToken;
swapAssets[1] = makerToken;
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
@@ -157,7 +124,7 @@ contract BalancerV2Sampler is SamplerUtils {
}
function _createSwapSteps(
BalancerV2PoolInfo memory poolInfo,
IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo,
uint256 amount
) private pure returns (IBalancerV2Vault.BatchSwapStep[] memory) {
IBalancerV2Vault.BatchSwapStep[] memory swapSteps =
@@ -172,18 +139,4 @@ contract BalancerV2Sampler is SamplerUtils {
return swapSteps;
}
function _createSwapFunds()
private
view
returns (IBalancerV2Vault.FundManagement memory)
{
return
IBalancerV2Vault.FundManagement({
sender: address(this),
fromInternalBalance: false,
recipient: payable(address(this)),
toInternalBalance: false
});
}
}

View File

@@ -22,9 +22,8 @@ pragma experimental ABIEncoderV2;
import "./interfaces/IBancor.sol";
contract CompilerHack {}
contract BancorSampler is CompilerHack {
contract BancorSampler {
/// @dev Base gas limit for Bancor calls.
uint256 constant private BANCOR_CALL_GAS = 300e3; // 300k

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "./BalancerSampler.sol";
import "./BalancerV2Sampler.sol";
import "./BalancerV2BatchSampler.sol";
import "./BancorSampler.sol";
import "./CompoundSampler.sol";
import "./CurveSampler.sol";
@@ -32,7 +33,6 @@ import "./KyberDmmSampler.sol";
import "./LidoSampler.sol";
import "./LiquidityProviderSampler.sol";
import "./MakerPSMSampler.sol";
import "./MultiBridgeSampler.sol";
import "./MStableSampler.sol";
import "./MooniswapSampler.sol";
import "./NativeOrderSampler.sol";
@@ -48,6 +48,7 @@ import "./UtilitySampler.sol";
contract ERC20BridgeSampler is
BalancerSampler,
BalancerV2Sampler,
BalancerV2BatchSampler,
BancorSampler,
CompoundSampler,
CurveSampler,
@@ -60,7 +61,6 @@ contract ERC20BridgeSampler is
MakerPSMSampler,
MStableSampler,
MooniswapSampler,
MultiBridgeSampler,
NativeOrderSampler,
ShellSampler,
SmoothySampler,
@@ -92,4 +92,6 @@ contract ERC20BridgeSampler is
(callResults[i].success, callResults[i].data) = address(this).call(callDatas[i]);
}
}
receive() external payable {}
}

View File

@@ -1,82 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IMultiBridge.sol";
contract MultiBridgeSampler {
/// @dev Default gas limit for multibridge calls.
uint256 constant private DEFAULT_CALL_GAS = 400e3; // 400k
/// @dev Sample sell quotes from MultiBridge.
/// @param multibridge Address of the MultiBridge contract.
/// @param takerToken Address of the taker token (what to sell).
/// @param intermediateToken The address of the intermediate token to
/// use in an indirect route.
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromMultiBridge(
address multibridge,
address takerToken,
address intermediateToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
// Initialize array of maker token amounts.
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
// If no address provided, return all zeros.
if (multibridge == address(0)) {
return makerTokenAmounts;
}
for (uint256 i = 0; i < numSamples; i++) {
(bool didSucceed, bytes memory resultData) =
multibridge.staticcall.gas(DEFAULT_CALL_GAS)(
abi.encodeWithSelector(
IMultiBridge(0).getSellQuote.selector,
takerToken,
intermediateToken,
makerToken,
takerTokenAmounts[i]
));
uint256 buyAmount = 0;
if (didSucceed) {
buyAmount = abi.decode(resultData, (uint256));
}
// Exit early if the amount is too high for the source to serve
if (buyAmount == 0) {
break;
}
makerTokenAmounts[i] = buyAmount;
}
}
}

View File

@@ -22,17 +22,43 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
interface IUniswapV3Quoter {
interface IUniswapV3QuoterV2 {
function factory()
external
view
returns (IUniswapV3Factory factory);
// @notice Returns the amount out received for a given exact input swap without executing the swap
// @param path The path of the swap, i.e. each token pair and the pool fee
// @param amountIn The amount of the first token to swap
// @return amountOut The amount of the last token that would be received
// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path
// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path
// @return gasEstimate The estimate of the gas that the swap consumes
function quoteExactInput(bytes memory path, uint256 amountIn)
external
returns (uint256 amountOut);
returns (
uint256 amountOut,
uint160[] memory sqrtPriceX96AfterList,
uint32[] memory initializedTicksCrossedList,
uint256 gasEstimate
);
// @notice Returns the amount in required for a given exact output swap without executing the swap
// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order
// @param amountOut The amount of the last token to receive
// @return amountIn The amount of first token required to be paid
// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path
// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path
// @return gasEstimate The estimate of the gas that the swap consumes
function quoteExactOutput(bytes memory path, uint256 amountOut)
external
returns (uint256 amountIn);
returns (
uint256 amountIn,
uint160[] memory sqrtPriceX96AfterList,
uint32[] memory initializedTicksCrossedList,
uint256 gasEstimate
);
}
interface IUniswapV3Factory {
@@ -51,23 +77,25 @@ interface IUniswapV3Pool {
contract UniswapV3Sampler
{
/// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
uint256 constant private QUOTE_GAS = 600e3;
uint256 constant private QUOTE_GAS = 700e3;
/// @dev Sample sell quotes from UniswapV3.
/// @param quoter UniswapV3 Quoter contract.
/// @param path Token route. Should be takerToken -> makerToken
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return uniswapPaths The encoded uniswap path for each sample.
/// @return uniswapGasUsed Estimated amount of gas used
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswapV3(
IUniswapV3Quoter quoter,
IUniswapV3QuoterV2 quoter,
IERC20TokenV06[] memory path,
uint256[] memory takerTokenAmounts
)
public
returns (
bytes[] memory uniswapPaths,
uint256[] memory uniswapGasUsed,
uint256[] memory makerTokenAmounts
)
{
@@ -76,31 +104,39 @@ contract UniswapV3Sampler
makerTokenAmounts = new uint256[](takerTokenAmounts.length);
uniswapPaths = new bytes[](takerTokenAmounts.length);
uniswapGasUsed = new uint256[](takerTokenAmounts.length);
for (uint256 i = 0; i < takerTokenAmounts.length; ++i) {
// Pick the best result from all the paths.
bytes memory topUniswapPath;
uint256 topBuyAmount = 0;
for (uint256 j = 0; j < poolPaths.length; ++j) {
bytes memory uniswapPath = _toUniswapPath(path, poolPaths[j]);
try
quoter.quoteExactInput
{ gas: QUOTE_GAS }
(uniswapPath, takerTokenAmounts[i])
returns (uint256 buyAmount)
try quoter.quoteExactInput
{ gas: QUOTE_GAS }
(uniswapPath, takerTokenAmounts[i])
returns (
uint256 buyAmount,
uint160[] memory, /* sqrtPriceX96AfterList */
uint32[] memory, /* initializedTicksCrossedList */
uint256 gasUsed
)
{
if (topBuyAmount <= buyAmount) {
topBuyAmount = buyAmount;
topUniswapPath = uniswapPath;
uniswapPaths[i] = uniswapPath;
uniswapGasUsed[i] = gasUsed;
}
} catch { }
} catch {}
}
// Break early if we can't complete the buys.
// Break early if we can't complete the sells.
if (topBuyAmount == 0) {
// HACK(kimpers): To avoid too many local variables, paths and gas used is set directly in the loop
// then reset if no valid valid quote was found
uniswapPaths[i] = "";
uniswapGasUsed[i] = 0;
break;
}
makerTokenAmounts[i] = topBuyAmount;
uniswapPaths[i] = topUniswapPath;
}
}
@@ -109,16 +145,18 @@ contract UniswapV3Sampler
/// @param path Token route. Should be takerToken -> makerToken.
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return uniswapPaths The encoded uniswap path for each sample.
/// @return uniswapGasUsed Estimated amount of gas used
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswapV3(
IUniswapV3Quoter quoter,
IUniswapV3QuoterV2 quoter,
IERC20TokenV06[] memory path,
uint256[] memory makerTokenAmounts
)
public
returns (
bytes[] memory uniswapPaths,
uint256[] memory uniswapGasUsed,
uint256[] memory takerTokenAmounts
)
{
@@ -128,10 +166,10 @@ contract UniswapV3Sampler
takerTokenAmounts = new uint256[](makerTokenAmounts.length);
uniswapPaths = new bytes[](makerTokenAmounts.length);
uniswapGasUsed = new uint256[](makerTokenAmounts.length);
for (uint256 i = 0; i < makerTokenAmounts.length; ++i) {
// Pick the best result from all the paths.
bytes memory topUniswapPath;
uint256 topSellAmount = 0;
for (uint256 j = 0; j < poolPaths.length; ++j) {
// quoter requires path to be reversed for buys.
@@ -143,21 +181,30 @@ contract UniswapV3Sampler
quoter.quoteExactOutput
{ gas: QUOTE_GAS }
(uniswapPath, makerTokenAmounts[i])
returns (uint256 sellAmount)
returns (
uint256 sellAmount,
uint160[] memory, /* sqrtPriceX96AfterList */
uint32[] memory, /* initializedTicksCrossedList */
uint256 gasUsed
)
{
if (topSellAmount == 0 || topSellAmount >= sellAmount) {
topSellAmount = sellAmount;
// But the output path should still be encoded for sells.
topUniswapPath = _toUniswapPath(path, poolPaths[j]);
uniswapPaths[i] = _toUniswapPath(path, poolPaths[j]);
uniswapGasUsed[i] = gasUsed;
}
} catch {}
}
// Break early if we can't complete the buys.
if (topSellAmount == 0) {
// HACK(kimpers): To avoid too many local variables, paths and gas used is set directly in the loop
// then reset if no valid valid quote was found
uniswapPaths[i] = "";
uniswapGasUsed[i] = 0;
break;
}
takerTokenAmounts[i] = topSellAmount;
uniswapPaths[i] = topUniswapPath;
}
}
@@ -236,6 +283,7 @@ contract UniswapV3Sampler
function _reverseTokenPath(IERC20TokenV06[] memory tokenPath)
private
pure
returns (IERC20TokenV06[] memory reversed)
{
reversed = new IERC20TokenV06[](tokenPath.length);
@@ -246,6 +294,7 @@ contract UniswapV3Sampler
function _reversePoolPath(IUniswapV3Pool[] memory poolPath)
private
pure
returns (IUniswapV3Pool[] memory reversed)
{
reversed = new IUniswapV3Pool[](poolPath.length);

View File

@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
/// @dev Minimal Balancer V2 Vault interface
/// for documentation refer to https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/vault/interfaces/IVault.sol
interface IBalancerV2Vault {
enum SwapKind { GIVEN_IN, GIVEN_OUT }
struct BatchSwapStep {
bytes32 poolId;
uint256 assetInIndex;
uint256 assetOutIndex;
uint256 amount;
bytes userData;
}
struct FundManagement {
address sender;
bool fromInternalBalance;
address payable recipient;
bool toInternalBalance;
}
struct BalancerV2PoolInfo {
bytes32 poolId;
address vault;
}
function queryBatchSwap(
SwapKind kind,
BatchSwapStep[] calldata swaps,
address[] calldata assets,
FundManagement calldata funds
) external returns (int256[] memory assetDeltas);
}

View File

@@ -1,39 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
contract DummyLiquidityProvider
{
/// @dev Quotes the amount of `makerToken` that would be obtained by
/// selling `sellAmount` of `takerToken`.
/// @param sellAmount Amount of `takerToken` to sell.
/// @return makerTokenAmount Amount of `makerToken` that would be obtained.
function getSellQuote(
address, /* takerToken */
address, /* makerToken */
uint256 sellAmount
)
external
view
returns (uint256 makerTokenAmount)
{
makerTokenAmount = sellAmount - 1;
}
/// @dev Quotes the amount of `takerToken` that would need to be sold in
/// order to obtain `buyAmount` of `makerToken`.
/// @param buyAmount Amount of `makerToken` to buy.
/// @return takerTokenAmount Amount of `takerToken` that would need to be sold.
function getBuyQuote(
address, /* takerToken */
address, /* makerToken */
uint256 buyAmount
)
external
view
returns (uint256 takerTokenAmount)
{
takerTokenAmount = buyAmount + 1;
}
}

View File

@@ -1,455 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "../src/ERC20BridgeSampler.sol";
import "../src/interfaces/IKyberNetwork.sol";
import "../src/interfaces/IUniswapV2Router01.sol";
library LibDeterministicQuotes {
address private constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
uint256 private constant RATE_DENOMINATOR = 1 ether;
uint256 private constant MIN_RATE = RATE_DENOMINATOR / 100;
uint256 private constant MAX_RATE = 100 * RATE_DENOMINATOR;
uint8 private constant MIN_DECIMALS = 4;
uint8 private constant MAX_DECIMALS = 20;
function getDeterministicSellQuote(
bytes32 salt,
address sellToken,
address buyToken,
uint256 sellAmount
)
internal
pure
returns (uint256 buyAmount)
{
uint256 sellBase = uint256(10) ** getDeterministicTokenDecimals(sellToken);
uint256 buyBase = uint256(10) ** getDeterministicTokenDecimals(buyToken);
uint256 rate = getDeterministicRate(salt, sellToken, buyToken);
return sellAmount * rate * buyBase / sellBase / RATE_DENOMINATOR;
}
function getDeterministicBuyQuote(
bytes32 salt,
address sellToken,
address buyToken,
uint256 buyAmount
)
internal
pure
returns (uint256 sellAmount)
{
uint256 sellBase = uint256(10) ** getDeterministicTokenDecimals(sellToken);
uint256 buyBase = uint256(10) ** getDeterministicTokenDecimals(buyToken);
uint256 rate = getDeterministicRate(salt, sellToken, buyToken);
return buyAmount * RATE_DENOMINATOR * sellBase / rate / buyBase;
}
function getDeterministicTokenDecimals(address token)
internal
pure
returns (uint8 decimals)
{
if (token == WETH_ADDRESS) {
return 18;
}
bytes32 seed = keccak256(abi.encodePacked(token));
return uint8(uint256(seed) % (MAX_DECIMALS - MIN_DECIMALS)) + MIN_DECIMALS;
}
function getDeterministicRate(bytes32 salt, address sellToken, address buyToken)
internal
pure
returns (uint256 rate)
{
bytes32 seed = keccak256(abi.encodePacked(salt, sellToken, buyToken));
return uint256(seed) % (MAX_RATE - MIN_RATE) + MIN_RATE;
}
}
contract TestDeploymentConstants {
// solhint-disable separate-by-one-line-in-contract
// Mainnet addresses ///////////////////////////////////////////////////////
/// @dev Mainnet address of the WETH contract.
address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
/// @dev Overridable way to get the WETH address.
/// @return wethAddress The WETH address.
function _getWethAddress()
internal
view
returns (address wethAddress)
{
return WETH_ADDRESS;
}
}
contract FailTrigger {
// Give this address a balance to force operations to fail.
address payable constant public FAILURE_ADDRESS = 0xe9dB8717BC5DFB20aaf538b4a5a02B7791FF430C;
// Funds `FAILURE_ADDRESS`.
function enableFailTrigger() external payable {
FAILURE_ADDRESS.transfer(msg.value);
}
function _revertIfShouldFail() internal view {
if (FAILURE_ADDRESS.balance != 0) {
revert("FAIL_TRIGGERED");
}
}
}
contract TestERC20BridgeSamplerUniswapExchange is
IUniswapExchangeQuotes,
TestDeploymentConstants,
FailTrigger
{
bytes32 constant private BASE_SALT = 0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab;
address public tokenAddress;
bytes32 public salt;
constructor(address _tokenAddress) public {
tokenAddress = _tokenAddress;
salt = keccak256(abi.encodePacked(BASE_SALT, _tokenAddress));
}
// Deterministic `IUniswapExchangeQuotes.getEthToTokenInputPrice()`.
function getEthToTokenInputPrice(
uint256 ethSold
)
override
external
view
returns (uint256 tokensBought)
{
_revertIfShouldFail();
return LibDeterministicQuotes.getDeterministicSellQuote(
salt,
tokenAddress,
_getWethAddress(),
ethSold
);
}
// Deterministic `IUniswapExchangeQuotes.getEthToTokenOutputPrice()`.
function getEthToTokenOutputPrice(
uint256 tokensBought
)
override
external
view
returns (uint256 ethSold)
{
_revertIfShouldFail();
return LibDeterministicQuotes.getDeterministicBuyQuote(
salt,
_getWethAddress(),
tokenAddress,
tokensBought
);
}
// Deterministic `IUniswapExchangeQuotes.getTokenToEthInputPrice()`.
function getTokenToEthInputPrice(
uint256 tokensSold
)
override
external
view
returns (uint256 ethBought)
{
_revertIfShouldFail();
return LibDeterministicQuotes.getDeterministicSellQuote(
salt,
tokenAddress,
_getWethAddress(),
tokensSold
);
}
// Deterministic `IUniswapExchangeQuotes.getTokenToEthOutputPrice()`.
function getTokenToEthOutputPrice(
uint256 ethBought
)
override
external
view
returns (uint256 tokensSold)
{
_revertIfShouldFail();
return LibDeterministicQuotes.getDeterministicBuyQuote(
salt,
_getWethAddress(),
tokenAddress,
ethBought
);
}
}
contract TestERC20BridgeSamplerUniswapV2Router01 is
IUniswapV2Router01,
TestDeploymentConstants,
FailTrigger
{
bytes32 constant private SALT = 0xadc7fcb33c735913b8635927e66896b356a53a912ab2ceff929e60a04b53b3c1;
// Deterministic `IUniswapV2Router01.getAmountsOut()`.
function getAmountsOut(uint256 amountIn, address[] calldata path)
override
external
view
returns (uint256[] memory amounts)
{
require(path.length >= 2, "PATH_TOO_SHORT");
_revertIfShouldFail();
amounts = new uint256[](path.length);
amounts[0] = amountIn;
for (uint256 i = 0; i < path.length - 1; ++i) {
amounts[i + 1] = LibDeterministicQuotes.getDeterministicSellQuote(
SALT,
path[i],
path[i + 1],
amounts[i]
);
}
}
// Deterministic `IUniswapV2Router01.getAmountsInt()`.
function getAmountsIn(uint256 amountOut, address[] calldata path)
override
external
view
returns (uint256[] memory amounts)
{
require(path.length >= 2, "PATH_TOO_SHORT");
_revertIfShouldFail();
amounts = new uint256[](path.length);
amounts[path.length - 1] = amountOut;
for (uint256 i = path.length - 1; i > 0; --i) {
amounts[i - 1] = LibDeterministicQuotes.getDeterministicBuyQuote(
SALT,
path[i - 1],
path[i],
amounts[i]
);
}
}
}
// solhint-disable space-after-comma
contract TestERC20BridgeSamplerKyberNetwork is
TestDeploymentConstants,
FailTrigger
{
bytes32 constant private SALT = 0x0ff3ca9d46195c39f9a12afb74207b4970349fb3cfb1e459bbf170298d326bc7;
address constant public ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
enum TradeType {BestOfAll, MaskIn, MaskOut, Split}
enum ProcessWithRate {NotRequired, Required}
// IKyberHintHandler
function buildTokenToEthHint(
address tokenSrc,
TradeType /* tokenToEthType */,
bytes32[] calldata /* tokenToEthReserveIds */,
uint256[] calldata /* tokenToEthSplits */
) external view returns (bytes memory hint)
{
return abi.encode(tokenSrc);
}
function buildEthToTokenHint(
address tokenDest,
TradeType /* ethToTokenType */,
bytes32[] calldata /* ethToTokenReserveIds */,
uint256[] calldata /* ethToTokenSplits */
) external view returns (bytes memory hint)
{
return abi.encode(tokenDest);
}
// IKyberHintHandler
function buildTokenToTokenHint(
address tokenSrc,
TradeType /* tokenToEthType */,
bytes32[] calldata /* tokenToEthReserveIds */,
uint256[] calldata /* tokenToEthSplits */,
address /* tokenDest */,
TradeType /* EthToTokenType */,
bytes32[] calldata /* EthToTokenReserveIds */,
uint256[] calldata /* EthToTokenSplits */
) external view returns (bytes memory hint)
{
return abi.encode(tokenSrc);
}
// IKyberHintHandler
function getTradingReserves(
address tokenSrc,
address tokenDest,
bool isTokenToToken,
bytes calldata hint
)
external
view
returns (
bytes32[] memory reserveIds,
uint256[] memory splitValuesBps,
ProcessWithRate processWithRate
)
{
reserveIds = new bytes32[](1);
reserveIds[0] = bytes32(uint256(1));
splitValuesBps = new uint256[](0);
processWithRate = ProcessWithRate.NotRequired;
}
// Deterministic `IKyberNetworkProxy.getExpectedRateAfterFee()`.
function getExpectedRateAfterFee(
address fromToken,
address toToken,
uint256 /* srcQty */,
uint256 /* fee */,
bytes calldata /* hint */
)
external
view
returns
(uint256 expectedRate)
{
_revertIfShouldFail();
fromToken = fromToken == ETH_ADDRESS ? _getWethAddress() : fromToken;
toToken = toToken == ETH_ADDRESS ? _getWethAddress() : toToken;
expectedRate = LibDeterministicQuotes.getDeterministicRate(
SALT,
fromToken,
toToken
);
}
// Deterministic `IKyberNetworkProxy.getExpectedRate()`.
function getExpectedRate(
address fromToken,
address toToken,
uint256
)
external
view
returns (uint256 expectedRate, uint256)
{
_revertIfShouldFail();
fromToken = fromToken == ETH_ADDRESS ? _getWethAddress() : fromToken;
toToken = toToken == ETH_ADDRESS ? _getWethAddress() : toToken;
expectedRate = LibDeterministicQuotes.getDeterministicRate(
SALT,
fromToken,
toToken
);
}
}
contract TestERC20BridgeSamplerUniswapExchangeFactory is
IUniswapExchangeFactory
{
mapping (address => IUniswapExchangeQuotes) private _exchangesByToken;
// Creates Uniswap exchange contracts for tokens.
function createTokenExchanges(address[] calldata tokenAddresses)
external
{
for (uint256 i = 0; i < tokenAddresses.length; i++) {
address tokenAddress = tokenAddresses[i];
_exchangesByToken[tokenAddress] =
new TestERC20BridgeSamplerUniswapExchange(tokenAddress);
}
}
// `IUniswapExchangeFactory.getExchange()`.
function getExchange(address tokenAddress)
override
external
view
returns (address)
{
return address(_exchangesByToken[tokenAddress]);
}
}
contract TestERC20BridgeSampler is
ERC20BridgeSampler,
FailTrigger
{
TestERC20BridgeSamplerUniswapExchangeFactory public uniswap;
TestERC20BridgeSamplerUniswapV2Router01 public uniswapV2Router;
TestERC20BridgeSamplerKyberNetwork public kyber;
uint8 private constant MAX_ORDER_STATUS = uint8(IExchange.OrderStatus.CANCELLED) + 1;
constructor() public ERC20BridgeSampler() {
uniswap = new TestERC20BridgeSamplerUniswapExchangeFactory();
uniswapV2Router = new TestERC20BridgeSamplerUniswapV2Router01();
kyber = new TestERC20BridgeSamplerKyberNetwork();
}
// Creates Uniswap exchange contracts for tokens.
function createTokenExchanges(address[] calldata tokenAddresses)
external
{
uniswap.createTokenExchanges(tokenAddresses);
}
// Overridden to return deterministic states.
function getLimitOrderFillableTakerAmount(
IExchange.LimitOrder memory order,
IExchange.Signature memory,
IExchange
)
override
public
view
returns (uint256 fillableTakerAmount)
{
return uint256(keccak256(abi.encode(order.salt))) % order.takerAmount;
}
// Overriden to return deterministic decimals.
function _getTokenDecimals(address tokenAddress)
override
internal
view
returns (uint8 decimals)
{
return LibDeterministicQuotes.getDeterministicTokenDecimals(tokenAddress);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/asset-swapper",
"version": "16.49.9",
"version": "16.57.3",
"engines": {
"node": ">=6.12"
},
@@ -39,7 +39,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|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|IBalancer|IBalancerV2Vault|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
"postpublish": {
"assets": []
}
@@ -58,21 +58,22 @@
"registry": "git@github.com:0xProject/gitpkg-registry.git"
},
"dependencies": {
"@0x/assert": "^3.0.31",
"@0x/base-contract": "^6.4.5",
"@0x/contract-addresses": "^6.11.0",
"@0x/contract-wrappers": "^13.19.0",
"@0x/contracts-erc20": "^3.3.26",
"@0x/contracts-zero-ex": "^0.31.0",
"@0x/dev-utils": "^4.2.11",
"@0x/json-schemas": "^6.4.1",
"@0x/neon-router": "^0.3.3",
"@0x/protocol-utils": "^1.11.0",
"@0x/assert": "^3.0.34",
"@0x/base-contract": "^6.5.0",
"@0x/contract-addresses": "^6.13.0",
"@0x/contract-wrappers": "^13.20.1",
"@0x/contracts-erc20": "^3.3.29",
"@0x/contracts-zero-ex": "^0.32.0",
"@0x/dev-utils": "^4.2.14",
"@0x/json-schemas": "^6.4.4",
"@0x/neon-router": "^0.3.5",
"@0x/protocol-utils": "^11.12.0",
"@0x/quote-server": "^6.0.6",
"@0x/types": "^3.3.4",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"@0x/types": "^3.3.6",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"@balancer-labs/sdk": "^0.1.6",
"@balancer-labs/sor": "0.3.2",
"@bancor/sdk": "0.2.9",
"@ethersproject/abi": "^5.0.1",
@@ -84,29 +85,30 @@
"axios-mock-adapter": "^1.19.0",
"cream-sor": "^0.3.3",
"decimal.js": "^10.2.0",
"ethereum-types": "^3.6.0",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.0.10",
"fast-abi": "^0.0.4",
"graphql": "^15.4.0",
"graphql-request": "^3.4.0",
"heartbeats": "^5.0.1",
"lodash": "^4.17.11"
"lodash": "^4.17.11",
"sorV2": "npm:@balancer-labs/sor"
},
"devDependencies": {
"@0x/abi-gen": "^5.7.2",
"@0x/abi-gen": "^5.8.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-libs": "^4.3.37",
"@0x/contracts-gen": "^2.0.43",
"@0x/contracts-test-utils": "^5.4.17",
"@0x/contracts-utils": "^4.8.7",
"@0x/contracts-gen": "^2.0.46",
"@0x/contracts-test-utils": "^5.4.20",
"@0x/contracts-utils": "^4.8.10",
"@0x/mesh-rpc-client": "^9.4.2",
"@0x/migrations": "^8.1.15",
"@0x/sol-compiler": "^4.7.8",
"@0x/subproviders": "^6.6.2",
"@0x/migrations": "^8.1.18",
"@0x/sol-compiler": "^4.8.1",
"@0x/subproviders": "^6.6.5",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.4",
"@0x/types": "^3.3.6",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -123,7 +125,7 @@
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typemoq": "^2.1.0",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"publishConfig": {
"access": "public"

View File

@@ -0,0 +1,57 @@
import { BigNumber } from '@0x/utils';
import { ZERO_AMOUNT } from '../constants';
export interface GeistInfo {
lendingPool: string;
gToken: string;
underlyingToken: string;
}
// tslint:disable-next-line:no-unnecessary-class
export class GeistSampler {
public static sampleSellsFromGeist(
geistInfo: GeistInfo,
takerToken: string,
makerToken: string,
takerTokenAmounts: BigNumber[],
): BigNumber[] {
// Deposit/Withdrawal underlying <-> gToken is always 1:1
if (
(takerToken.toLowerCase() === geistInfo.gToken.toLowerCase() &&
makerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase()) ||
(takerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase() &&
makerToken.toLowerCase() === geistInfo.gToken.toLowerCase())
) {
return takerTokenAmounts;
}
// Not matching the reserve return 0 results
const numSamples = takerTokenAmounts.length;
const makerTokenAmounts = new Array(numSamples);
makerTokenAmounts.fill(ZERO_AMOUNT);
return makerTokenAmounts;
}
public static sampleBuysFromGeist(
geistInfo: GeistInfo,
takerToken: string,
makerToken: string,
makerTokenAmounts: BigNumber[],
): BigNumber[] {
// Deposit/Withdrawal underlying <-> gToken is always 1:1
if (
(takerToken.toLowerCase() === geistInfo.gToken.toLowerCase() &&
makerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase()) ||
(takerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase() &&
makerToken.toLowerCase() === geistInfo.gToken.toLowerCase())
) {
return makerTokenAmounts;
}
// Not matching the reserve return 0 results
const numSamples = makerTokenAmounts.length;
const takerTokenAmounts = new Array(numSamples);
takerTokenAmounts.fill(ZERO_AMOUNT);
return takerTokenAmounts;
}
}

View File

@@ -42,6 +42,7 @@ import {
FinalUniswapV3FillData,
LiquidityProviderFillData,
MooniswapFillData,
NativeRfqOrderFillData,
OptimizedMarketBridgeOrder,
OptimizedMarketOrder,
UniswapV2FillData,
@@ -60,6 +61,7 @@ import {
isDirectSwapCompatible,
isMultiplexBatchFillCompatible,
isMultiplexMultiHopFillCompatible,
requiresTransformERC20,
} from './quote_consumer_utils';
// tslint:disable-next-line:custom-no-magic-numbers
@@ -333,6 +335,49 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
};
}
// RFQT VIP
if (
[ChainId.Mainnet, ChainId.Polygon].includes(this.chainId) &&
!isToETH &&
!isFromETH &&
quote.orders.every(o => o.type === FillQuoteTransformerOrderType.Rfq) &&
!requiresTransformERC20(optsWithDefaults)
) {
const rfqOrdersData = quote.orders.map(o => o.fillData as NativeRfqOrderFillData);
const fillAmountPerOrder = (() => {
// Don't think order taker amounts are clipped to actual sell amount
// (the last one might be too large) so figure them out manually.
let remaining = sellAmount;
const fillAmounts = [];
for (const o of quote.orders) {
const fillAmount = BigNumber.min(o.takerAmount, remaining);
fillAmounts.push(fillAmount);
remaining = remaining.minus(fillAmount);
}
return fillAmounts;
})();
const callData =
quote.orders.length === 1
? this._exchangeProxy
.fillRfqOrder(rfqOrdersData[0].order, rfqOrdersData[0].signature, fillAmountPerOrder[0])
.getABIEncodedTransactionData()
: this._exchangeProxy
.batchFillRfqOrders(
rfqOrdersData.map(d => d.order),
rfqOrdersData.map(d => d.signature),
fillAmountPerOrder,
true,
)
.getABIEncodedTransactionData();
return {
calldataHexString: callData,
ethAmount: ZERO_AMOUNT,
toAddress: this._exchangeProxy.address,
allowanceTarget: this._exchangeProxy.address,
gasOverhead: ZERO_AMOUNT,
};
}
if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
return {
calldataHexString: this._encodeMultiplexBatchFillCalldata(

View File

@@ -519,7 +519,7 @@ function createSwapQuote(
: calculateQuoteInfo(optimizedOrders, operation, assetFillAmount, gasPrice, gasSchedule, slippage);
// Put together the swap quote
const { makerTokenDecimals, takerTokenDecimals } = optimizerResult.marketSideLiquidity;
const { makerTokenDecimals, takerTokenDecimals, blockNumber } = optimizerResult.marketSideLiquidity;
const swapQuote = {
makerToken,
takerToken,
@@ -536,6 +536,7 @@ function createSwapQuote(
extendedQuoteReportSources,
isTwoHop,
priceComparisonsReport,
blockNumber,
};
if (operation === MarketOperation.Buy) {

View File

@@ -179,6 +179,7 @@ export interface SwapQuoteBase {
takerTokenDecimals: number;
takerAmountPerEth: BigNumber;
makerAmountPerEth: BigNumber;
blockNumber: number;
}
/**

View File

@@ -31,6 +31,7 @@ import {
KYBER_BRIDGED_LIQUIDITY_PREFIX,
MAX_DODOV2_POOLS_QUERIED,
MAX_KYBER_RESERVES_QUERIED,
MOBIUSMONEY_CELO_INFOS,
MORPHEUSSWAP_ROUTER_BY_CHAIN_ID,
MSTABLE_POOLS_BY_CHAIN_ID,
NERVE_BSC_INFOS,
@@ -449,6 +450,18 @@ export function getAcryptosInfosForPair(chainId: ChainId, takerToken: string, ma
),
);
}
export function getMobiusMoneyInfoForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
if (chainId !== ChainId.Celo) {
return [];
}
return Object.values(MOBIUSMONEY_CELO_INFOS).filter(c =>
[makerToken, takerToken].every(
t =>
(c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
),
);
}
export function getShellLikeInfosForPair(
chainId: ChainId,
@@ -491,7 +504,8 @@ export function getCurveLikeInfosForPair(
| ERC20BridgeSource.IronSwap
| ERC20BridgeSource.XSigma
| ERC20BridgeSource.FirebirdOneSwap
| ERC20BridgeSource.ACryptos,
| ERC20BridgeSource.ACryptos
| ERC20BridgeSource.MobiusMoney,
): CurveDetailedInfo[] {
let pools: CurveInfo[] = [];
switch (source) {
@@ -537,6 +551,9 @@ export function getCurveLikeInfosForPair(
case ERC20BridgeSource.ACryptos:
pools = getAcryptosInfosForPair(chainId, takerToken, makerToken);
break;
case ERC20BridgeSource.MobiusMoney:
pools = getMobiusMoneyInfoForPair(chainId, takerToken, makerToken);
break;
default:
throw new Error(`Unknown Curve like source ${source}`);
}

View File

@@ -8,6 +8,7 @@ import { TokenAdjacencyGraphBuilder } from '../token_adjacency_graph_builder';
import { SourceFilters } from './source_filters';
import {
AaveV2FillData,
BalancerV2BatchSwapFillData,
BancorFillData,
CompoundFillData,
CurveFillData,
@@ -17,7 +18,10 @@ import {
ERC20BridgeSource,
FeeSchedule,
FillData,
FinalUniswapV3FillData,
GeistFillData,
GetMarketOrdersOpts,
isFinalUniswapV3FillData,
KyberSamplerOpts,
LidoInfo,
LiquidityProviderFillData,
@@ -187,6 +191,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Beethovenx,
ERC20BridgeSource.Curve,
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.Geist,
ERC20BridgeSource.JetSwap,
ERC20BridgeSource.MorpheusSwap,
ERC20BridgeSource.SpiritSwap,
@@ -198,6 +203,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.UbeSwap,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.MobiusMoney,
]),
[ChainId.Optimism]: new SourceFilters([
ERC20BridgeSource.UniswapV3,
@@ -275,6 +281,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Mooniswap,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Nerve,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.PancakeSwap,
ERC20BridgeSource.PancakeSwapV2,
ERC20BridgeSource.SushiSwap,
@@ -331,6 +338,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Beethovenx,
ERC20BridgeSource.Curve,
ERC20BridgeSource.CurveV2,
ERC20BridgeSource.Geist,
ERC20BridgeSource.JetSwap,
ERC20BridgeSource.MorpheusSwap,
ERC20BridgeSource.SpiritSwap,
@@ -342,6 +350,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.UbeSwap,
ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop,
ERC20BridgeSource.MobiusMoney,
]),
[ChainId.Optimism]: new SourceFilters([
ERC20BridgeSource.UniswapV3,
@@ -470,10 +479,13 @@ export const MAINNET_TOKENS = {
alUSD: '0xbc6da0fe9ad5f3b0d58160288917aa56653660e9',
// Frax ecosystem
FRAX: '0x853d955acef822db058eb8505911ed77f175b99e',
cvxFXS: '0xfeef77d3f69374f66429c91d732a244f074bdf74',
FXS: '0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0',
OHM: '0x383518188c0c6d7730d91b2c03a03c837814a899',
OHMV2: '0x64aa3364f17a4d01c6f1751fd97c2bd3d7e7f1d5',
BTRFLY: '0xc0d4ceb216b3ba9c3701b291766fdcba977cec3a',
// Stargate
STG: '0xaf5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6',
//
LUSD: '0x5f98805a4e8be255a32880fdec7f6728c6568ba0',
// Fei Ecosystem
@@ -495,6 +507,7 @@ export const MAINNET_TOKENS = {
OUSD: '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86',
agEUR: '0x1a7e4e63778b4f12a199c062f3efdd288afcbce8',
ibEUR: '0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27',
YFI: '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e',
};
export const BSC_TOKENS = {
@@ -530,6 +543,7 @@ export const POLYGON_TOKENS = {
BANANA: '0x5d47baba0d66083c52009271faf3f50dcc01023c',
WEXPOLY: '0x4c4bf319237d98a30a929a96112effa8da3510eb',
nUSD: '0xb6c473756050de474286bed418b77aeac39b02af',
ANY: '0x6aB6d61428fde76768D7b45D8BFeec19c6eF91A8',
};
export const AVALANCHE_TOKENS = {
@@ -549,6 +563,7 @@ export const AVALANCHE_TOKENS = {
nUSD: '0xcfc37a6ab183dd4aed08c204d1c2773c0b1bdf46',
aWETH: '0x53f7c5869a859f0aec3d334ee8b4cf01e3492f21',
MIM: '0x130966628846bfd36ff31a822705796e8cb8c18d',
MAG: '0x1d60109178C48E4A937D8AB71699D8eBb6F7c5dE',
};
export const CELO_TOKENS = {
@@ -556,11 +571,11 @@ export const CELO_TOKENS = {
// Some of these tokens are Optics bridge? tokens which
// had an issue and migrated from v1 to v2
WETHv1: '0xe919f65739c26a42616b7b8eedc6b5524d1e3ac4',
WETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455',
oWETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455',
WBTC: '0xbaab46e28388d2779e6e31fd00cf0e5ad95e327b',
cUSD: '0x765de816845861e75a25fca122bb6898b8b1282a',
// ??
WBTCv1: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b',
cBTC: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b',
cETH: '0x2def4285787d58a2f811af24755a8150622f4361',
UBE: '0x00be915b9dcf56a3cbe739d9b9c202ca692409ec',
// Moolah
@@ -569,6 +584,22 @@ export const CELO_TOKENS = {
mCEUR: '0xe273ad7ee11dcfaa87383ad5977ee1504ac07568',
amCUSD: '0x64defa3544c695db8c535d289d843a189aa26b98',
MOO: '0x17700282592d6917f6a73d0bf8accf4d578c131e',
//
wBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
wETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
wBTCO: '0xbe50a3013a1c94768a1abb78c3cb79ab28fc1ace',
pUSDC: '0xcc82628f6a8defa1e2b0ad7ed448bef3647f7941',
cUSDC: '0x2a3684e9dc20b857375ea04235f2f7edbe818fa7',
cUSDC_V2: '0xef4229c8c3250c675f21bcefa42f58efbff6002a',
pUSDC_V2: '0x1bfc26ce035c368503fae319cc2596716428ca44',
pUSD: '0xeadf4a7168a82d30ba0619e64d5bcf5b30b45226',
pCELO: '0x301a61d01a63c8d670c2b8a43f37d12ef181f997',
aaUSDC: '0xb70e0a782b058bfdb0d109a3599bec1f19328e36',
asUSDC: '0xcd7d7ff64746c1909e44db8e95331f9316478817',
mcUSDT: '0xcfffe0c89a779c09df3df5624f54cdf7ef5fdd5d',
mcUSDC: '0x93db49be12b864019da9cb147ba75cdc0506190e',
DAI: '0x90ca507a5d4458a4c6c6249d186b6dcb02a5bccd',
};
export const FANTOM_TOKENS = {
@@ -578,6 +609,7 @@ export const FANTOM_TOKENS = {
DAI: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e',
fUSDT: '0x049d68029688eabf473097a2fc38ef61633a3c7a',
WBTC: '0x321162cd933e2be498cd2267a90534a804051b11',
WCRV: '0x1e4f97b9f9f913c46f1632781732927b9019c68b',
renBTC: '0xdbf31df14b66535af65aac99c32e9ea844e14501',
MIM: '0x82f0b8b456c1a451378467398982d4834b6829c1',
nUSD: '0xed2a7edd7413021d440b09d654f3b87712abab66',
@@ -586,6 +618,15 @@ export const FANTOM_TOKENS = {
gUSDC: '0xe578c856933d8e1082740bf7661e379aa2a30b26',
gDAI: '0x07e6332dd090d287d3489245038daf987955dcfb',
FRAX: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355',
gFTM: '0x39b3bd37208cbade74d0fcbdbb12d606295b430a',
gETH: '0x25c130b2624cf12a4ea30143ef50c5d68cefa22f',
gWBTC: '0x38aca5484b8603373acc6961ecd57a6a594510a3',
gCRV: '0x690754a168b022331caa2467207c61919b3f8a98',
gMIM: '0xc664fc7b8487a3e10824cda768c1d239f2403bbe',
};
export const GEIST_FANTOM_POOLS = {
lendingPool: '0x9fad24f572045c7869117160a571b2e50b10d068',
};
export const OPTIMISM_TOKENS = {
@@ -631,6 +672,8 @@ export const CURVE_POOLS = {
USDP: '0x42d7025938bec20b69cbae5a77421082407f053a', // usdp
ib: '0x2dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf', // iron bank
link: '0xf178c0b5bb7e7abf4e12a4838c7b7c5ba2c623c0', // link
btrflyweth: '0xf43b15ab692fde1f9c24a9fce700adcc809d5391', // redacted cartel
stgusdc: '0x3211c6cbef1429da3d0d58494938299c92ad5860', // stargate
// StableSwap "open pools" (crv.finance)
TUSD: '0xecd5e75afb02efa118af914515d6521aabd189f1',
STABLEx: '0x3252efd4ea2d6c78091a1f43982ee2c3659cc3d1',
@@ -640,6 +683,7 @@ export const CURVE_POOLS = {
BUSD: '0x4807862aa8b2bf68830e4c8dc86d0e9a998e085a',
DSU3CRV: '0x6ec80df362d7042c50d4469bcfbc174c9dd9109a',
cvxcrv: '0x9d0464996170c6b9e75eed71c68b99ddedf279e8',
cvxfxs: '0xd658a338613198204dca1143ac3f01a722b5d94a',
mim: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
eurt: '0xfd5db7463a3ab53fd211b4af195c5bccc1a03890',
ethcrv: '0x8301ae4fc9c624d1d396cbdaa1ed877821d7c511',
@@ -653,6 +697,7 @@ export const CURVE_POOLS = {
d3pool: '0xbaaa1f5dba42c3389bdbc2c9d2de134f5cd0dc89',
triEURpool: '0xb9446c4ef5ebe66268da6700d26f96273de3d571',
ibEURsEUR: '0x19b080fe1ffa0553469d20ca36219f17fcf03859',
wethyfi: '0xc26b89a667578ec7b3f11b2f98d6fd15c07c54ba',
};
export const CURVE_V2_POOLS = {
@@ -780,6 +825,14 @@ export const FIREBIRDONESWAP_BSC_POOLS = {
export const FIREBIRDONESWAP_POLYGON_POOLS = {
oneswap: '0x01c9475dbd36e46d1961572c8de24b74616bae9e',
};
export const MOBIUSMONEY_CELO_POOLS = {
usdc_optics_v2: '0x9906589ea8fd27504974b7e8201df5bbde986b03',
dai_optics_v2: '0xf3f65dfe0c8c8f2986da0fec159abe6fd4e700b4',
weth_optics_v2: '0x74ef28d635c6c5800dd3cd62d4c4f8752daacb09',
pusdc_optics_v2: '0xcce0d62ce14fb3e4363eb92db37ff3630836c252',
usdc_allbridge_solana: '0x63c1914bf00a9b395a2bf89aada55a5615a3656e',
usdc_poly_optics: '0xa2f0e57d4ceacf025e81c76f28b9ad6e9fbe8735',
};
export const ACRYPTOS_POOLS = {
acs4usd: '0xb3f0c9ea1f05e312093fdb031e789a756659b0ac',
@@ -829,6 +882,7 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
AVALANCHE_TOKENS.nUSD,
AVALANCHE_TOKENS.nETH,
AVALANCHE_TOKENS.aWETH,
AVALANCHE_TOKENS.MIM,
],
[ChainId.Fantom]: [
FANTOM_TOKENS.WFTM,
@@ -839,7 +893,13 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
FANTOM_TOKENS.nETH,
FANTOM_TOKENS.MIM,
],
[ChainId.Celo]: [CELO_TOKENS.WCELO, CELO_TOKENS.mCUSD, CELO_TOKENS.WETH, CELO_TOKENS.amCUSD, CELO_TOKENS.WBTC],
[ChainId.Celo]: [
CELO_TOKENS.WCELO,
CELO_TOKENS.mCUSD,
CELO_TOKENS.WETHv1,
CELO_TOKENS.amCUSD,
CELO_TOKENS.WBTC,
],
[ChainId.Optimism]: [
OPTIMISM_TOKENS.WETH,
OPTIMISM_TOKENS.DAI,
@@ -864,6 +924,8 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
builder.add(MAINNET_TOKENS.MIR, MAINNET_TOKENS.UST);
// Convex and Curve
builder.add(MAINNET_TOKENS.cvxCRV, MAINNET_TOKENS.CRV).add(MAINNET_TOKENS.CRV, MAINNET_TOKENS.cvxCRV);
// Convex and FXS
builder.add(MAINNET_TOKENS.cvxFXS, MAINNET_TOKENS.FXS).add(MAINNET_TOKENS.FXS, MAINNET_TOKENS.cvxFXS);
// FEI TRIBE liquid in UniV2
builder.add(MAINNET_TOKENS.FEI, MAINNET_TOKENS.TRIBE).add(MAINNET_TOKENS.TRIBE, MAINNET_TOKENS.FEI);
// FRAX ecosystem
@@ -881,15 +943,21 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
}).build(),
[ChainId.Polygon]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Polygon],
}).build(),
})
.tap(builder => {
builder.add(POLYGON_TOKENS.QUICK, POLYGON_TOKENS.ANY).add(POLYGON_TOKENS.ANY, POLYGON_TOKENS.QUICK);
})
.build(),
[ChainId.Avalanche]: new TokenAdjacencyGraphBuilder({
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Avalanche],
})
.tap(builder => {
// Synape nETH/aWETH pool
// Synapse nETH/aWETH pool
builder
.add(AVALANCHE_TOKENS.aWETH, AVALANCHE_TOKENS.nETH)
.add(AVALANCHE_TOKENS.nETH, AVALANCHE_TOKENS.aWETH);
// Trader Joe MAG/MIM pool
builder.add(AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.MAG).add(AVALANCHE_TOKENS.MAG, AVALANCHE_TOKENS.MIM);
})
.build(),
[ChainId.Fantom]: new TokenAdjacencyGraphBuilder({
@@ -1004,6 +1072,25 @@ const createCurveV2MetaTriPool = (info: { tokens: string[]; pool: string; gasSch
gasSchedule: info.gasSchedule,
});
const createCurveFactoryCryptoExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_uint256,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_uint256,
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: info.tokens,
metaTokens: undefined,
poolAddress: info.pool,
gasSchedule: info.gasSchedule,
});
const MOBIUSMONEY_CELO_SHARED: CurveInfo = {
exchangeFunctionSelector: CurveFunctionSelectors.swap,
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
metaTokens: undefined,
gasSchedule: 150e3,
poolAddress: NULL_ADDRESS,
tokens: [],
};
/**
* Mainnet Curve configuration
* The tokens are in order of their index, which each curve defines
@@ -1270,6 +1357,26 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
pool: CURVE_POOLS.ibEURsEUR,
gasSchedule: 176e3,
}),
[CURVE_POOLS.btrflyweth]: createCurveFactoryCryptoExchangePool({
tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.BTRFLY],
pool: CURVE_POOLS.btrflyweth,
gasSchedule: 250e3,
}),
[CURVE_POOLS.wethyfi]: createCurveFactoryCryptoExchangePool({
tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.YFI],
pool: CURVE_POOLS.wethyfi,
gasSchedule: 250e3,
}),
[CURVE_POOLS.stgusdc]: createCurveFactoryCryptoExchangePool({
tokens: [MAINNET_TOKENS.STG, MAINNET_TOKENS.USDC],
pool: CURVE_POOLS.stgusdc,
gasSchedule: 250e3,
}),
[CURVE_POOLS.cvxfxs]: createCurveFactoryCryptoExchangePool({
tokens: [MAINNET_TOKENS.FXS, MAINNET_TOKENS.cvxFXS],
pool: CURVE_POOLS.cvxfxs,
gasSchedule: 390e3,
}),
};
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
@@ -1665,6 +1772,39 @@ export const FIREBIRDONESWAP_POLYGON_INFOS: { [name: string]: CurveInfo } = {
},
};
export const MOBIUSMONEY_CELO_INFOS: { [name: string]: CurveInfo } = {
[MOBIUSMONEY_CELO_POOLS.usdc_optics_v2]: {
...MOBIUSMONEY_CELO_SHARED,
poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_optics_v2,
tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.cUSDC_V2],
},
[MOBIUSMONEY_CELO_POOLS.weth_optics_v2]: {
...MOBIUSMONEY_CELO_SHARED,
poolAddress: MOBIUSMONEY_CELO_POOLS.weth_optics_v2,
tokens: [CELO_TOKENS.cETH, CELO_TOKENS.oWETH],
},
[MOBIUSMONEY_CELO_POOLS.pusdc_optics_v2]: {
...MOBIUSMONEY_CELO_SHARED,
poolAddress: MOBIUSMONEY_CELO_POOLS.pusdc_optics_v2,
tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.pUSDC_V2],
},
[MOBIUSMONEY_CELO_POOLS.usdc_allbridge_solana]: {
...MOBIUSMONEY_CELO_SHARED,
poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_allbridge_solana,
tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.asUSDC],
},
[MOBIUSMONEY_CELO_POOLS.usdc_poly_optics]: {
...MOBIUSMONEY_CELO_SHARED,
poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_poly_optics,
tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.pUSD],
},
[MOBIUSMONEY_CELO_POOLS.dai_optics_v2]: {
...MOBIUSMONEY_CELO_SHARED,
poolAddress: MOBIUSMONEY_CELO_POOLS.dai_optics_v2,
tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.DAI],
},
};
const ACRYPTOS_ACS4USD_POOL_BSC_TOKENS = [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.DAI, BSC_TOKENS.USDC];
const createAcryptosMetaUsdPool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
@@ -1996,6 +2136,13 @@ export const COMPONENT_POOLS_BY_CHAIN_ID = valueByChainId(
},
);
export const GEIST_INFO_ADDRESS_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Fantom]: '0xd8321aa83fb0a4ecd6348d4577431310a6e0814d',
},
NULL_ADDRESS,
);
export const BALANCER_V2_VAULT_ADDRESS_BY_CHAIN = valueByChainId<string>(
{
[ChainId.Mainnet]: '0xba12222222228d8ba445958a75a0704d566bf2c8',
@@ -2028,11 +2175,12 @@ export const BALANCER_SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/ba
export const BALANCER_TOP_POOLS_FETCHED = 250;
export const BALANCER_MAX_POOLS_FETCHED = 3;
export const BALANCER_V2_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
export const BALANCER_V2_SUBGRAPH_URL_BY_CHAIN = valueByChainId(
{
[ChainId.Mainnet]: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2',
[ChainId.Polygon]: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-polygon-v2',
},
'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2',
null,
);
export const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
@@ -2045,19 +2193,19 @@ export const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
{
[ChainId.Mainnet]: {
quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6',
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.Ropsten]: {
quoter: '0x2f9e608fd881861b8916257b76613cb22ee0652c',
router: '0x03782388516e94fcd4c18666303601a12aa729ea',
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.Polygon]: {
quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6',
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
[ChainId.Optimism]: {
quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6',
quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e',
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
},
},
@@ -2297,6 +2445,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
[ERC20BridgeSource.IronSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.XSigma]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.FirebirdOneSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.MobiusMoney]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.MultiBridge]: () => 350e3,
[ERC20BridgeSource.UniswapV2]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.SushiSwap]: uniswapV2CloneGasSchedule,
@@ -2304,7 +2453,9 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
[ERC20BridgeSource.Linkswap]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.ShibaSwap]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.Balancer]: () => 120e3,
[ERC20BridgeSource.BalancerV2]: () => 100e3,
[ERC20BridgeSource.BalancerV2]: (fillData?: FillData) => {
return 100e3 + ((fillData as BalancerV2BatchSwapFillData).swapSteps.length - 1) * 50e3;
},
[ERC20BridgeSource.Cream]: () => 120e3,
[ERC20BridgeSource.MStable]: () => 200e3,
[ERC20BridgeSource.MakerPsm]: (fillData?: FillData) => {
@@ -2349,11 +2500,34 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
return gas;
},
[ERC20BridgeSource.UniswapV3]: (fillData?: FillData) => {
let gas = 100e3;
const path = (fillData as UniswapV3FillData).tokenAddressPath;
if (path.length > 2) {
gas += (path.length - 2) * 32e3; // +32k for each hop.
const uniFillData = fillData as UniswapV3FillData | FinalUniswapV3FillData;
// NOTE: This base value was heuristically chosen by looking at how much it generally
// underestimated gas usage
const base = 34e3; // 34k base
let gas = base;
if (isFinalUniswapV3FillData(uniFillData)) {
gas += uniFillData.gasUsed;
} else {
// NOTE: We don't actually know which of the paths would be used in the router
// therefore we estimate using the median of gas usage returned from UniswapV3
// For the best case scenario (least amount of hops & ticks) this will
// overestimate the gas usage
const pathAmountsWithGasUsed = uniFillData.pathAmounts.filter(p => p.gasUsed > 0);
const medianGasUsedForPath =
pathAmountsWithGasUsed[Math.floor(pathAmountsWithGasUsed.length / 2)]?.gasUsed ?? 0;
gas += medianGasUsedForPath;
}
// If we for some reason could not read `gasUsed` when sampling
// fall back to legacy gas estimation
if (gas === base) {
gas = 100e3;
const path = uniFillData.tokenAddressPath;
if (path.length > 2) {
gas += (path.length - 2) * 32e3; // +32k for each hop.
}
}
return gas;
},
[ERC20BridgeSource.Lido]: () => 226e3,
@@ -2362,6 +2536,10 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
// NOTE: The Aave deposit method is more expensive than the withdraw
return aaveFillData.takerToken === aaveFillData.underlyingToken ? 400e3 : 300e3;
},
[ERC20BridgeSource.Geist]: (fillData?: FillData) => {
const geistFillData = fillData as GeistFillData;
return geistFillData.takerToken === geistFillData.underlyingToken ? 400e3 : 300e3;
},
[ERC20BridgeSource.Compound]: (fillData?: FillData) => {
// NOTE: cETH is handled differently than other cTokens
const wethAddress = NATIVE_FEE_TOKEN_BY_CHAIN_ID[ChainId.Mainnet];

View File

@@ -175,9 +175,9 @@ export function dexSamplesToFills(
const { source, fillData } = sample;
const input = sample.input.minus(prevSample ? prevSample.input : 0);
const output = sample.output.minus(prevSample ? prevSample.output : 0);
const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0;
let penalty = ZERO_AMOUNT;
if (i === 0) {
const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0;
// Only the first fill in a DEX path incurs a penalty.
penalty = ethToOutputAmount({
input,

View File

@@ -0,0 +1,36 @@
import { FANTOM_TOKENS, GEIST_FANTOM_POOLS } from './constants';
import { GeistInfo } from './types';
const gTokenToUnderlyingToken = new Map<string, string>([
[FANTOM_TOKENS.gFTM, FANTOM_TOKENS.WFTM],
[FANTOM_TOKENS.gfUSDT, FANTOM_TOKENS.fUSDT],
[FANTOM_TOKENS.gDAI, FANTOM_TOKENS.DAI],
[FANTOM_TOKENS.gUSDC, FANTOM_TOKENS.USDC],
[FANTOM_TOKENS.gETH, FANTOM_TOKENS.WETH],
[FANTOM_TOKENS.gWBTC, FANTOM_TOKENS.WBTC],
[FANTOM_TOKENS.gCRV, FANTOM_TOKENS.WCRV],
[FANTOM_TOKENS.gMIM, FANTOM_TOKENS.MIM],
]);
/**
* Returns GeistInfo for a certain pair if that pair exists on Geist
*/
export function getGeistInfoForPair(takerToken: string, makerToken: string): GeistInfo | undefined {
let gToken;
let underlyingToken;
if (gTokenToUnderlyingToken.get(takerToken) === makerToken) {
gToken = takerToken;
underlyingToken = makerToken;
} else if (gTokenToUnderlyingToken.get(makerToken) === takerToken) {
gToken = makerToken;
underlyingToken = takerToken;
} else {
return undefined;
}
return {
lendingPool: GEIST_FANTOM_POOLS.lendingPool,
gToken,
underlyingToken,
};
}

View File

@@ -42,7 +42,7 @@ import { createFills } from './fills';
import { getBestTwoHopQuote } from './multihop_utils';
import { createOrdersFromTwoHopSample } from './orders';
import { Path, PathPenaltyOpts } from './path';
import { fillsToSortedPaths, findOptimalPathJSAsync, findOptimalRustPathFromSamples } from './path_optimizer';
import { findOptimalPathJSAsync, findOptimalRustPathFromSamples } from './path_optimizer';
import { DexOrderSampler, getSampleAmounts } from './sampler';
import { SourceFilters } from './source_filters';
import {
@@ -241,6 +241,7 @@ export class MarketOperationUtils {
dexQuotes,
},
isRfqSupported,
blockNumber: blockNumber.toNumber(),
};
}
@@ -269,6 +270,7 @@ export class MarketOperationUtils {
// Call the sampler contract.
const samplerPromise = this._sampler.executeAsync(
this._sampler.getBlockNumber(),
this._sampler.getTokenDecimals([makerToken, takerToken]),
// Get native order fillable amounts.
this._sampler.getLimitOrderFillableMakerAmounts(nativeOrders, this.contractAddresses.exchangeProxy),
@@ -302,6 +304,7 @@ export class MarketOperationUtils {
const [
[
blockNumber,
tokenDecimals,
orderFillableMakerAmounts,
ethToMakerAssetRate,
@@ -342,6 +345,7 @@ export class MarketOperationUtils {
dexQuotes,
},
isRfqSupported,
blockNumber: blockNumber.toNumber(),
};
}
@@ -372,6 +376,7 @@ export class MarketOperationUtils {
const feeSourceFilters = this._feeSources.exclude(_opts.excludedFeeSources);
const ops = [
this._sampler.getBlockNumber(),
...batchNativeOrders.map(orders =>
this._sampler.getLimitOrderFillableMakerAmounts(orders, this.contractAddresses.exchangeProxy),
),
@@ -396,13 +401,15 @@ export class MarketOperationUtils {
),
];
const executeResults = await this._sampler.executeBatchAsync(ops);
const [blockNumberRaw, ...executeResults] = await this._sampler.executeBatchAsync(ops);
const batchOrderFillableMakerAmounts = executeResults.splice(0, batchNativeOrders.length) as BigNumber[][];
const batchEthToTakerAssetRate = executeResults.splice(0, batchNativeOrders.length) as BigNumber[];
const batchDexQuotes = executeResults.splice(0, batchNativeOrders.length) as DexSample[][][];
const batchTokenDecimals = executeResults.splice(0, batchNativeOrders.length) as number[][];
const inputAmountPerEth = ZERO_AMOUNT;
const blockNumber: number = (blockNumberRaw as BigNumber).toNumber();
return Promise.all(
batchNativeOrders.map(async (nativeOrders, i) => {
if (nativeOrders.length === 0) {
@@ -435,6 +442,7 @@ export class MarketOperationUtils {
twoHopQuotes: [],
},
isRfqSupported: false,
blockNumber,
},
{
bridgeSlippage: _opts.bridgeSlippage,
@@ -493,18 +501,6 @@ export class MarketOperationUtils {
} as NativeOrderWithFillableAmounts),
);
// Convert native orders and dex quotes into `Fill` objects.
const fills = createFills({
side,
orders: [...nativeOrders, ...augmentedRfqtIndicativeQuotes],
dexQuotes,
targetInput: inputAmount,
outputAmountPerEth,
inputAmountPerEth,
excludedSources: opts.excludedSources,
feeSchedule: opts.feeSchedule,
});
// Find the optimal path.
const penaltyOpts: PathPenaltyOpts = {
outputAmountPerEth,
@@ -517,13 +513,11 @@ export class MarketOperationUtils {
const takerAmountPerEth = side === MarketOperation.Sell ? inputAmountPerEth : outputAmountPerEth;
const makerAmountPerEth = side === MarketOperation.Sell ? outputAmountPerEth : inputAmountPerEth;
// Find the unoptimized best rate to calculate savings from optimizer
const _unoptimizedPath = fillsToSortedPaths(fills, side, inputAmount, penaltyOpts)[0];
const unoptimizedPath = _unoptimizedPath ? _unoptimizedPath.collapse(orderOpts) : undefined;
let fills: Fill[][];
// Find the optimal path using Rust router if enabled, otherwise fallback to JS Router
let optimalPath: Path | undefined;
if (SHOULD_USE_RUST_ROUTER) {
fills = [[]];
optimalPath = findOptimalRustPathFromSamples(
side,
dexQuotes,
@@ -536,6 +530,18 @@ export class MarketOperationUtils {
opts.samplerMetrics,
);
} else {
// Convert native orders and dex quotes into `Fill` objects.
fills = createFills({
side,
orders: [...nativeOrders, ...augmentedRfqtIndicativeQuotes],
dexQuotes,
targetInput: inputAmount,
outputAmountPerEth,
inputAmountPerEth,
excludedSources: opts.excludedSources,
feeSchedule: opts.feeSchedule,
});
optimalPath = await findOptimalPathJSAsync(
side,
fills,
@@ -561,7 +567,6 @@ export class MarketOperationUtils {
sourceFlags: SOURCE_FLAGS[ERC20BridgeSource.MultiHop],
marketSideLiquidity,
adjustedRate: bestTwoHopRate,
unoptimizedPath,
takerAmountPerEth,
makerAmountPerEth,
};
@@ -573,7 +578,10 @@ export class MarketOperationUtils {
}
// Generate a fallback path if required
await this._addOptionalFallbackAsync(side, inputAmount, optimalPath, dexQuotes, fills, opts, penaltyOpts);
// TODO(kimpers): Will experiment with disabling this and see how it affects revert rate
// to avoid yet another router roundtrip
// TODO: clean this up if we don't need it
// await this._addOptionalFallbackAsync(side, inputAmount, optimalPath, dexQuotes, fills, opts, penaltyOpts);
const collapsedPath = optimalPath.collapse(orderOpts);
return {
@@ -582,7 +590,6 @@ export class MarketOperationUtils {
sourceFlags: collapsedPath.sourceFlags,
marketSideLiquidity,
adjustedRate: optimalPathRate,
unoptimizedPath,
takerAmountPerEth,
makerAmountPerEth,
};
@@ -770,7 +777,7 @@ export class MarketOperationUtils {
private async _refreshPoolCacheIfRequiredAsync(takerToken: string, makerToken: string): Promise<void> {
void Promise.all(
Object.values(this._sampler.poolsCaches).map(async cache => {
if (cache.isFresh(takerToken, makerToken)) {
if (!cache || cache.isFresh(takerToken, makerToken)) {
return Promise.resolve([]);
}
return cache.getFreshPoolsForPairAsync(takerToken, makerToken);
@@ -778,6 +785,8 @@ export class MarketOperationUtils {
);
}
/*
* TODO(kimpers): Remove this when we know that it's safe to drop the fallbacks on native orders
// tslint:disable-next-line: prefer-function-over-method
private async _addOptionalFallbackAsync(
side: MarketOperation,
@@ -843,6 +852,7 @@ export class MarketOperationUtils {
}
}
}
*/
}
// tslint:disable: max-file-line-count

View File

@@ -8,6 +8,7 @@ import {
AaveV2FillData,
AggregationError,
BalancerFillData,
BalancerV2BatchSwapFillData,
BalancerV2FillData,
BancorFillData,
CollapsedFill,
@@ -18,6 +19,7 @@ import {
ERC20BridgeSource,
FillData,
FinalUniswapV3FillData,
GeistFillData,
GenericRouterFillData,
KyberDmmFillData,
KyberFillData,
@@ -36,6 +38,7 @@ import {
ShellFillData,
UniswapV2FillData,
UniswapV3FillData,
UniswapV3PathAmount,
} from './types';
// tslint:disable completed-docs
@@ -84,7 +87,7 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
case ERC20BridgeSource.Balancer:
return encodeBridgeSourceId(BridgeProtocol.Balancer, 'Balancer');
case ERC20BridgeSource.BalancerV2:
return encodeBridgeSourceId(BridgeProtocol.BalancerV2, 'BalancerV2');
return encodeBridgeSourceId(BridgeProtocol.BalancerV2Batch, 'BalancerV2');
case ERC20BridgeSource.Bancor:
return encodeBridgeSourceId(BridgeProtocol.Bancor, 'Bancor');
// case ERC20BridgeSource.CoFiX:
@@ -202,6 +205,10 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'AaveV2');
case ERC20BridgeSource.Compound:
return encodeBridgeSourceId(BridgeProtocol.Compound, 'Compound');
case ERC20BridgeSource.Geist:
return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'Geist');
case ERC20BridgeSource.MobiusMoney:
return encodeBridgeSourceId(BridgeProtocol.Nerve, 'MobiusMoney');
default:
throw new Error(AggregationError.NoBridgeForSource);
}
@@ -237,6 +244,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
case ERC20BridgeSource.FirebirdOneSwap:
case ERC20BridgeSource.IronSwap:
case ERC20BridgeSource.ACryptos:
case ERC20BridgeSource.MobiusMoney:
const curveFillData = (order as OptimizedMarketBridgeOrder<CurveFillData>).fillData;
bridgeData = encoder.encode([
curveFillData.pool.poolAddress,
@@ -251,9 +259,18 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
bridgeData = encoder.encode([balancerFillData.poolAddress]);
break;
case ERC20BridgeSource.BalancerV2:
{
const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2BatchSwapFillData>).fillData;
bridgeData = encoder.encode([
balancerV2FillData.vault,
balancerV2FillData.swapSteps,
balancerV2FillData.assets,
]);
}
break;
case ERC20BridgeSource.Beethovenx:
const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
const { vault, poolId } = balancerV2FillData;
const beethovenFillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
const { vault, poolId } = beethovenFillData;
bridgeData = encoder.encode([vault, poolId]);
break;
case ERC20BridgeSource.Bancor:
@@ -356,6 +373,10 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
const compoundFillData = (order as OptimizedMarketBridgeOrder<CompoundFillData>).fillData;
bridgeData = encoder.encode([compoundFillData.cToken]);
break;
case ERC20BridgeSource.Geist:
const geistFillData = (order as OptimizedMarketBridgeOrder<GeistFillData>).fillData;
bridgeData = encoder.encode([geistFillData.lendingPool, geistFillData.gToken]);
break;
default:
throw new Error(AggregationError.NoBridgeForSource);
@@ -387,11 +408,14 @@ function createFinalBridgeOrderFillDataFromCollapsedFill(fill: CollapsedFill): F
switch (fill.source) {
case ERC20BridgeSource.UniswapV3: {
const fd = fill.fillData as UniswapV3FillData;
return {
const { uniswapPath, gasUsed } = getBestUniswapV3PathAmountForInputAmount(fd, fill.input);
const finalFillData: FinalUniswapV3FillData = {
router: fd.router,
tokenAddressPath: fd.tokenAddressPath,
uniswapPath: getBestUniswapV3PathForInputAmount(fd, fill.input),
uniswapPath,
gasUsed,
};
return finalFillData;
}
default:
break;
@@ -399,18 +423,21 @@ function createFinalBridgeOrderFillDataFromCollapsedFill(fill: CollapsedFill): F
return fill.fillData;
}
function getBestUniswapV3PathForInputAmount(fillData: UniswapV3FillData, inputAmount: BigNumber): string {
function getBestUniswapV3PathAmountForInputAmount(
fillData: UniswapV3FillData,
inputAmount: BigNumber,
): UniswapV3PathAmount {
if (fillData.pathAmounts.length === 0) {
throw new Error(`No Uniswap V3 paths`);
}
// Find the best path that can satisfy `inputAmount`.
// Assumes `fillData.pathAmounts` is sorted ascending.
for (const { inputAmount: pathInputAmount, uniswapPath } of fillData.pathAmounts) {
if (pathInputAmount.gte(inputAmount)) {
return uniswapPath;
for (const pathAmount of fillData.pathAmounts) {
if (pathAmount.inputAmount.gte(inputAmount)) {
return pathAmount;
}
}
return fillData.pathAmounts[fillData.pathAmounts.length - 1].uniswapPath;
return fillData.pathAmounts[fillData.pathAmounts.length - 1];
}
export function getMakerTakerTokens(opts: CreateOrderFromPathOpts): [string, string] {
@@ -475,6 +502,7 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.FirebirdOneSwap]: curveEncoder,
[ERC20BridgeSource.IronSwap]: curveEncoder,
[ERC20BridgeSource.ACryptos]: curveEncoder,
[ERC20BridgeSource.MobiusMoney]: curveEncoder,
// UniswapV2 like, (router, address[])
[ERC20BridgeSource.Bancor]: routerAddressPathEncoder,
[ERC20BridgeSource.UniswapV2]: routerAddressPathEncoder,
@@ -515,7 +543,21 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.Uniswap]: poolEncoder,
// Custom integrations
[ERC20BridgeSource.MakerPsm]: makerPsmEncoder,
[ERC20BridgeSource.BalancerV2]: balancerV2Encoder,
[ERC20BridgeSource.BalancerV2]: AbiEncoder.create([
{ name: 'vault', type: 'address' },
{
name: 'swapSteps',
type: 'tuple[]',
components: [
{ name: 'poolId', type: 'bytes32' },
{ name: 'assetInIndex', type: 'uint256' },
{ name: 'assetOutIndex', type: 'uint256' },
{ name: 'amount', type: 'uint256' },
{ name: 'userData', type: 'bytes' },
],
},
{ name: 'assets', type: 'address[]' },
]),
[ERC20BridgeSource.Beethovenx]: balancerV2Encoder,
[ERC20BridgeSource.UniswapV3]: AbiEncoder.create([
{ name: 'router', type: 'address' },
@@ -525,6 +567,7 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.Lido]: AbiEncoder.create('(address)'),
[ERC20BridgeSource.AaveV2]: AbiEncoder.create('(address,address)'),
[ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'),
[ERC20BridgeSource.Geist]: AbiEncoder.create('(address,address)'),
};
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {

View File

@@ -122,17 +122,8 @@ export class Path {
++i;
continue;
}
// If there are contiguous bridge orders, we can batch them together.
// TODO jacob pretty sure this is from DFB and we can remove
const contiguousBridgeFills = [collapsedFills[i]];
for (let j = i + 1; j < collapsedFills.length; ++j) {
if (collapsedFills[j].source === ERC20BridgeSource.Native) {
break;
}
contiguousBridgeFills.push(collapsedFills[j]);
}
this.orders.push(createBridgeOrder(contiguousBridgeFills[0], makerToken, takerToken, opts.side));
this.orders.push(createBridgeOrder(collapsedFills[i], makerToken, takerToken, opts.side));
i += 1;
}
return this as CollapsedPath;

View File

@@ -76,11 +76,12 @@ function findRoutesAndCreateOptimalPath(
opts: PathPenaltyOpts,
fees: FeeSchedule,
neonRouterNumSamples: number,
): Path | undefined {
vipSourcesSet: Set<ERC20BridgeSource>,
): { allSourcesPath: Path | undefined; vipSourcesPath: Path | undefined } | undefined {
// Currently the rust router is unable to handle 1 base unit sized quotes and will error out
// To avoid flooding the logs with these errors we just return an insufficient liquidity error
// which is how the JS router handles these quotes today
if (input.eq(ONE_BASE_UNIT)) {
if (input.isLessThanOrEqualTo(ONE_BASE_UNIT)) {
return undefined;
}
@@ -94,6 +95,127 @@ function findRoutesAndCreateOptimalPath(
return fills[0];
};
const createPathFromStrategy = (sourcesRustRoute: Float64Array, sourcesOutputAmounts: Float64Array) => {
const routesAndSamplesAndOutputs = _.zip(
sourcesRustRoute,
samplesAndNativeOrdersWithResults,
sourcesOutputAmounts,
sampleSourcePathIds,
);
const adjustedFills: Fill[] = [];
const totalRoutedAmount = BigNumber.sum(...sourcesRustRoute);
const scale = input.dividedBy(totalRoutedAmount);
for (const [
routeInput,
routeSamplesAndNativeOrders,
outputAmount,
sourcePathId,
] of routesAndSamplesAndOutputs) {
if (!Number.isFinite(outputAmount)) {
DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`);
return undefined;
}
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) {
continue;
}
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
// we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much
const rustInputAdjusted = BigNumber.min(
new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL),
input,
);
const current = routeSamplesAndNativeOrders[routeSamplesAndNativeOrders.length - 1];
if (!isDexSample(current)) {
const nativeFill = nativeOrdersToFills(
side,
[current],
rustInputAdjusted,
opts.outputAmountPerEth,
opts.inputAmountPerEth,
fees,
false,
)[0] as Fill | undefined;
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
// and nativeFill will be `undefined`
if (nativeFill) {
// NOTE: For Limit/RFQ orders we are done here. No need to scale output
adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() });
}
continue;
}
// NOTE: For DexSamples only
let fill = createFill(current);
if (!fill) {
continue;
}
const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>;
// Descend to approach a closer fill for fillData which may not be consistent
// throughout the path (UniswapV3) and for a closer guesstimate at
// gas used
assert.assert(routeSamples.length >= 1, 'Found no sample to use for source');
for (let k = routeSamples.length - 1; k >= 0; k--) {
if (k === 0) {
fill = createFill(routeSamples[0]) ?? fill;
}
if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) {
const left = routeSamples[k];
const right = routeSamples[k + 1];
if (left && right) {
fill =
createFill({
...right, // default to the greater (for gas used)
input: rustInputAdjusted,
output: new BigNumber(outputAmount),
}) ?? fill;
} else {
assert.assert(Boolean(left || right), 'No valid sample to use');
fill = createFill(left || right) ?? fill;
}
break;
}
}
// TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router
const maxSampledOutput = BigNumber.max(...routeSamples.map(s => s.output));
// Scale output by scale factor but never go above the largest sample in sell quotes (unknown liquidity) or below 1 base unit (unfillable)
const scaleOutput = (output: BigNumber) => {
// Don't try to scale 0 output as it will be clamped to 1
if (output.eq(ZERO_AMOUNT)) {
return output;
}
const scaled = output
.times(scale)
.decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
const capped = MarketOperation.Sell ? BigNumber.min(scaled, maxSampledOutput) : scaled;
return BigNumber.max(capped, 1);
};
adjustedFills.push({
...fill,
input: rustInputAdjusted,
output: scaleOutput(fill.output),
adjustedOutput: scaleOutput(fill.adjustedOutput),
index: 0,
parent: undefined,
sourcePathId: sourcePathId ?? hexUtils.random(),
});
}
if (adjustedFills.length === 0) {
return undefined;
}
const pathFromRustInputs = Path.create(side, adjustedFills, input, opts);
return pathFromRustInputs;
};
const samplesAndNativeOrdersWithResults: Array<DexSample[] | NativeOrderWithFillableAmounts[]> = [];
const serializedPaths: SerializedPath[] = [];
const sampleSourcePathIds: string[] = [];
@@ -105,8 +227,9 @@ function findRoutesAndCreateOptimalPath(
const sourcePathId = hexUtils.random();
const singleSourceSamplesWithOutput = [...singleSourceSamples];
for (let i = singleSourceSamples.length - 1; i >= 0; i--) {
if (singleSourceSamples[i].output.isZero()) {
// Remove trailing 0 output samples
const currentOutput = singleSourceSamples[i].output;
if (currentOutput.isZero() || !currentOutput.isFinite()) {
// Remove trailing 0/invalid output samples
singleSourceSamplesWithOutput.pop();
} else {
break;
@@ -136,6 +259,7 @@ function findRoutesAndCreateOptimalPath(
inputs: [],
outputs: [],
outputFees: [],
isVip: vipSourcesSet.has(singleSourceSamplesWithOutput[0]?.source),
},
);
@@ -194,6 +318,7 @@ function findRoutesAndCreateOptimalPath(
inputs,
outputs,
outputFees,
isVip: true,
};
samplesAndNativeOrdersWithResults.push([nativeOrder]);
@@ -212,129 +337,42 @@ function findRoutesAndCreateOptimalPath(
};
const allSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
const strategySourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
route(rustArgs, allSourcesRustRoute, strategySourcesOutputAmounts, neonRouterNumSamples);
const allSourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
const vipSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
const vipSourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
route(
rustArgs,
allSourcesRustRoute,
allSourcesOutputAmounts,
vipSourcesRustRoute,
vipSourcesOutputAmounts,
neonRouterNumSamples,
);
assert.assert(
rustArgs.pathsIn.length === allSourcesRustRoute.length,
'different number of sources in the Router output than the input',
);
assert.assert(
rustArgs.pathsIn.length === strategySourcesOutputAmounts.length,
rustArgs.pathsIn.length === allSourcesOutputAmounts.length,
'different number of sources in the Router output amounts results than the input',
);
assert.assert(
rustArgs.pathsIn.length === vipSourcesRustRoute.length,
'different number of sources in the Router output than the input',
);
assert.assert(
rustArgs.pathsIn.length === vipSourcesOutputAmounts.length,
'different number of sources in the Router output amounts results than the input',
);
const routesAndSamplesAndOutputs = _.zip(
allSourcesRustRoute,
samplesAndNativeOrdersWithResults,
strategySourcesOutputAmounts,
sampleSourcePathIds,
);
const adjustedFills: Fill[] = [];
const totalRoutedAmount = BigNumber.sum(...allSourcesRustRoute);
const allSourcesPath = createPathFromStrategy(allSourcesRustRoute, allSourcesOutputAmounts);
const vipSourcesPath = createPathFromStrategy(vipSourcesRustRoute, vipSourcesOutputAmounts);
const scale = input.dividedBy(totalRoutedAmount);
for (const [routeInput, routeSamplesAndNativeOrders, outputAmount, sourcePathId] of routesAndSamplesAndOutputs) {
if (!Number.isFinite(outputAmount)) {
DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`);
return undefined;
}
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) {
continue;
}
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
// we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much
const rustInputAdjusted = BigNumber.min(
new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL),
input,
);
const current = routeSamplesAndNativeOrders[routeSamplesAndNativeOrders.length - 1];
if (!isDexSample(current)) {
const nativeFill = nativeOrdersToFills(
side,
[current],
rustInputAdjusted,
opts.outputAmountPerEth,
opts.inputAmountPerEth,
fees,
false,
)[0] as Fill | undefined;
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
// and nativeFill will be `undefined`
if (nativeFill) {
// NOTE: For Limit/RFQ orders we are done here. No need to scale output
adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() });
}
continue;
}
// NOTE: For DexSamples only
let fill = createFill(current);
if (!fill) {
continue;
}
const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>;
// Descend to approach a closer fill for fillData which may not be consistent
// throughout the path (UniswapV3) and for a closer guesstimate at
// gas used
assert.assert(routeSamples.length >= 1, 'Found no sample to use for source');
for (let k = routeSamples.length - 1; k >= 0; k--) {
if (k === 0) {
fill = createFill(routeSamples[0]) ?? fill;
}
if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) {
const left = routeSamples[k];
const right = routeSamples[k + 1];
if (left && right) {
fill =
createFill({
...right, // default to the greater (for gas used)
input: rustInputAdjusted,
output: new BigNumber(outputAmount),
}) ?? fill;
} else {
assert.assert(Boolean(left || right), 'No valid sample to use');
fill = createFill(left || right) ?? fill;
}
break;
}
}
// TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router
const maxSampledOutput = BigNumber.max(...routeSamples.map(s => s.output));
// Scale output by scale factor but never go above the largest sample (unknown liquidity) or below 1 base unit (unfillable)
const scaleOutput = (output: BigNumber) => {
// Don't try to scale 0 output as it will be clamped to 1
if (output.eq(ZERO_AMOUNT)) {
return output;
}
const scaled = output
.times(scale)
.decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
return BigNumber.max(BigNumber.min(scaled, maxSampledOutput), 1);
};
adjustedFills.push({
...fill,
input: rustInputAdjusted,
output: scaleOutput(fill.output),
adjustedOutput: scaleOutput(fill.adjustedOutput),
index: 0,
parent: undefined,
sourcePathId: sourcePathId ?? hexUtils.random(),
});
}
if (adjustedFills.length === 0) {
return undefined;
}
const pathFromRustInputs = Path.create(side, adjustedFills, input, opts);
return pathFromRustInputs;
return {
allSourcesPath,
vipSourcesPath,
};
}
export function findOptimalRustPathFromSamples(
@@ -348,9 +386,18 @@ export function findOptimalRustPathFromSamples(
neonRouterNumSamples: number,
samplerMetrics?: SamplerMetrics,
): Path | undefined {
const beforeAllTimeMs = performance.now();
let beforeTimeMs = performance.now();
const allSourcesPath = findRoutesAndCreateOptimalPath(
const beforeTimeMs = performance.now();
const sendMetrics = () => {
// tslint:disable-next-line: no-unused-expression
samplerMetrics &&
samplerMetrics.logRouterDetails({
router: 'neon-router',
type: 'total',
timingMs: performance.now() - beforeTimeMs,
});
};
const vipSourcesSet = new Set(VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID[chainId]);
const paths = findRoutesAndCreateOptimalPath(
side,
samples,
nativeOrders,
@@ -358,58 +405,22 @@ export function findOptimalRustPathFromSamples(
opts,
fees,
neonRouterNumSamples,
vipSourcesSet,
);
// tslint:disable-next-line: no-unused-expression
samplerMetrics &&
samplerMetrics.logRouterDetails({
router: 'neon-router',
type: 'all',
timingMs: performance.now() - beforeTimeMs,
});
if (!allSourcesPath) {
if (!paths) {
sendMetrics();
return undefined;
}
const vipSources = VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID[chainId];
const { allSourcesPath, vipSourcesPath } = paths;
// HACK(kimpers): The Rust router currently doesn't account for VIP sources correctly
// we need to try to route them in isolation and compare with the results all sources
if (vipSources.length > 0) {
beforeTimeMs = performance.now();
const vipSourcesSet = new Set(vipSources);
const vipSourcesSamples = samples.filter(s => s[0] && vipSourcesSet.has(s[0].source));
if (vipSourcesSamples.length > 0) {
const vipSourcesPath = findRoutesAndCreateOptimalPath(
side,
vipSourcesSamples,
[],
input,
opts,
fees,
neonRouterNumSamples,
);
// tslint:disable-next-line: no-unused-expression
samplerMetrics &&
samplerMetrics.logRouterDetails({
router: 'neon-router',
type: 'vip',
timingMs: performance.now() - beforeTimeMs,
});
if (vipSourcesPath?.isBetterThan(allSourcesPath)) {
return vipSourcesPath;
}
}
if (!allSourcesPath || vipSourcesPath?.isBetterThan(allSourcesPath)) {
sendMetrics();
return vipSourcesPath;
}
// tslint:disable-next-line: no-unused-expression
samplerMetrics &&
samplerMetrics.logRouterDetails({
router: 'neon-router',
type: 'total',
timingMs: performance.now() - beforeAllTimeMs,
});
sendMetrics();
return allSourcesPath;
}

View File

@@ -51,7 +51,7 @@ export class BalancerV2PoolsCache extends PoolsCache {
constructor(
chainId: ChainId,
private readonly subgraphUrl: string = BALANCER_V2_SUBGRAPH_URL_BY_CHAIN[chainId],
private readonly subgraphUrl: string = BALANCER_V2_SUBGRAPH_URL_BY_CHAIN[chainId]!,
private readonly maxPoolsFetched: number = BALANCER_MAX_POOLS_FETCHED,
private readonly _topPoolsFetched: number = BALANCER_TOP_POOLS_FETCHED,
private readonly _warningLogger: LogFunction = DEFAULT_WARNING_LOGGER,

View File

@@ -0,0 +1,190 @@
import { ChainId } from '@0x/contract-addresses';
import { BigNumber } from '@0x/utils';
import {
BalancerSDK,
BalancerSdkConfig,
formatSequence,
getTokenAddressesForSwap,
NewPath,
parseToPoolsDict,
PoolDictionary,
RouteProposer,
SwapTypes,
} from '@balancer-labs/sdk';
import { DEFAULT_WARNING_LOGGER } from '../../../constants';
import { LogFunction } from '../../../types';
import { BALANCER_V2_SUBGRAPH_URL_BY_CHAIN, ONE_SECOND_MS } from '../constants';
import { BalancerSwapInfo, BalancerSwaps } from '../types';
import { CacheValue, EMPTY_BALANCER_SWAPS, SwapInfoCache } from './pair_swaps_cache';
import { SubgraphPoolDataService } from './sgPoolDataService';
// tslint:disable-next-line:custom-no-magic-numbers
const ONE_DAY_MS = 24 * 60 * 60 * ONE_SECOND_MS;
export interface BalancerPoolResponse {
poolType: string;
id: string;
tokens: Array<{ address: string }>;
tokensList: string[];
}
export class BalancerV2SwapInfoCache extends SwapInfoCache {
private static readonly _MAX_POOLS_PER_PATH = 4;
private static readonly _MAX_CANDIDATE_PATHS_PER_PAIR = 2;
private readonly _routeProposer: RouteProposer;
private readonly _poolDataService: SubgraphPoolDataService;
constructor(
chainId: ChainId,
subgraphUrl: string | null = BALANCER_V2_SUBGRAPH_URL_BY_CHAIN[chainId],
private readonly _warningLogger: LogFunction = DEFAULT_WARNING_LOGGER,
cache: { [key: string]: CacheValue } = {},
) {
super(cache);
const config: BalancerSdkConfig = {
network: chainId as number, // wtf TS
rpcUrl: '', // Not actually used by SDK for this.
};
const balancerSdk = new BalancerSDK(config);
// The RouteProposer finds paths between a token pair using direct/multihop/linearPool routes
this._routeProposer = balancerSdk.sor.routeProposer;
// Uses Subgraph to retrieve up to date pool data required for routeProposer
this._poolDataService = new SubgraphPoolDataService({
chainId,
subgraphUrl,
});
void this._loadTopPoolsAsync();
// Reload the top pools every 12 hours
setInterval(async () => void this._loadTopPoolsAsync(), ONE_DAY_MS / 2);
}
protected async _loadTopPoolsAsync(): Promise<void> {
const fromToSwapInfo: {
[from: string]: { [to: string]: BalancerSwaps };
} = {};
// Retrieve pool data from Subgraph
const pools = await this._poolDataService.getPools();
// timestamp is used for Element pools
const timestamp = Math.floor(Date.now() / ONE_SECOND_MS);
const poolsDict = parseToPoolsDict(pools, timestamp);
for (const pool of pools) {
const { tokensList } = pool;
// tslint:disable-next-line: await-promise
await null; // This loop can be CPU heavy so yield to event loop.
for (const from of tokensList) {
for (const to of tokensList.filter(t => t.toLowerCase() !== from.toLowerCase())) {
fromToSwapInfo[from] = fromToSwapInfo[from] || {};
// If a record for pair already exists skip as all paths alreay found
if (fromToSwapInfo[from][to]) {
continue;
} else {
try {
const expiresAt = Date.now() + this._cacheTimeMs;
// Retrieve swap steps and assets for a token pair
// This only needs to be called once per pair as all paths will be created from single call
const pairSwapInfo = this._getPoolPairSwapInfo(poolsDict, from, to);
fromToSwapInfo[from][to] = pairSwapInfo;
this._cacheSwapInfoForPair(from, to, fromToSwapInfo[from][to], expiresAt);
} catch (err) {
this._warningLogger(err, `Failed to load Balancer V2 top pools`);
// soldier on
}
}
}
}
}
}
/**
* Will retrieve fresh pair and path data from Subgraph and return and array of swap info for pair..
* @param takerToken Address of takerToken.
* @param makerToken Address of makerToken.
* @returns Swap data for pair consisting of assets and swap steps for ExactIn and ExactOut swap types.
*/
protected async _fetchSwapInfoForPairAsync(takerToken: string, makerToken: string): Promise<BalancerSwaps> {
try {
// retrieve up to date pools from SG
const pools = await this._poolDataService.getPools();
// timestamp is used for Element pools
const timestamp = Math.floor(Date.now() / ONE_SECOND_MS);
const poolDictionary = parseToPoolsDict(pools, timestamp);
return this._getPoolPairSwapInfo(poolDictionary, takerToken, makerToken);
} catch (e) {
return EMPTY_BALANCER_SWAPS;
}
}
/**
* Uses pool data from provided dictionary to find top swap paths for token pair.
* @param pools Dictionary of pool data.
* @param takerToken Address of taker token.
* @param makerToken Address of maker token.
* @returns Swap data for pair consisting of assets and swap steps for ExactIn and ExactOut swap types.
*/
private _getPoolPairSwapInfo(pools: PoolDictionary, takerToken: string, makerToken: string): BalancerSwaps {
/*
Uses Balancer SDK to construct available paths for pair.
Paths can be direct, i.e. both tokens are in same pool or multihop.
Will also create paths for the new Balancer Linear pools.
These are returned in order of available liquidity which is useful for filtering.
*/
const paths = this._routeProposer.getCandidatePathsFromDict(
takerToken,
makerToken,
SwapTypes.SwapExactIn,
pools,
BalancerV2SwapInfoCache._MAX_POOLS_PER_PATH,
);
if (paths.length === 0) {
return EMPTY_BALANCER_SWAPS;
}
// Convert paths data to swap information suitable for queryBatchSwap. Only use top 2 liquid paths
return formatSwaps(paths.slice(0, BalancerV2SwapInfoCache._MAX_CANDIDATE_PATHS_PER_PAIR));
}
}
/**
* Given an array of Balancer paths, returns swap information that can be passed to queryBatchSwap.
* @param paths Array of Balancer paths.
* @returns Formatted swap data consisting of assets and swap steps for ExactIn and ExactOut swap types.
*/
function formatSwaps(paths: NewPath[]): BalancerSwaps {
const formattedSwapsExactIn: BalancerSwapInfo[] = [];
const formattedSwapsExactOut: BalancerSwapInfo[] = [];
let assets: string[];
paths.forEach(path => {
// Add a swap amount for each swap so we can use formatSequence. (This will be overwritten with actual amount during query)
path.swaps.forEach(s => (s.swapAmount = '0'));
const tokenAddresses = getTokenAddressesForSwap(path.swaps);
// Formats for both ExactIn and ExactOut swap types
const swapsExactIn = formatSequence(SwapTypes.SwapExactIn, path.swaps, tokenAddresses);
const swapsExactOut = formatSequence(SwapTypes.SwapExactOut, path.swaps, tokenAddresses);
assets = tokenAddresses;
formattedSwapsExactIn.push({
assets,
swapSteps: swapsExactIn.map(s => ({
...s,
amount: new BigNumber(s.amount),
})),
});
formattedSwapsExactOut.push({
assets,
swapSteps: swapsExactOut.map(s => ({
...s,
amount: new BigNumber(s.amount),
})),
});
});
const formattedSwaps: BalancerSwaps = {
swapInfoExactIn: formattedSwapsExactIn,
swapInfoExactOut: formattedSwapsExactOut,
};
return formattedSwaps;
}

View File

@@ -0,0 +1,91 @@
import { BalancerSwaps } from '../types';
import { ONE_HOUR_IN_SECONDS, ONE_SECOND_MS } from '../constants';
export interface CacheValue {
expiresAt: number;
balancerSwaps: BalancerSwaps;
}
// tslint:disable:custom-no-magic-numbers
// Cache results for 30mins
const DEFAULT_CACHE_TIME_MS = (ONE_HOUR_IN_SECONDS / 2) * ONE_SECOND_MS;
const DEFAULT_TIMEOUT_MS = ONE_SECOND_MS;
export const EMPTY_BALANCER_SWAPS = { swapInfoExactIn: [], swapInfoExactOut: [] };
// tslint:enable:custom-no-magic-numbers
/**
* Caches SwapInfo for a pair of tokens.
* SwapInfo includes swap steps and asset information for those swap steps.
*/
export abstract class SwapInfoCache {
protected static _isExpired(value: CacheValue): boolean {
return Date.now() >= value.expiresAt;
}
constructor(
protected readonly _cache: { [key: string]: CacheValue },
protected readonly _cacheTimeMs: number = DEFAULT_CACHE_TIME_MS,
) {}
public async getFreshPoolsForPairAsync(
takerToken: string,
makerToken: string,
timeoutMs: number = DEFAULT_TIMEOUT_MS,
): Promise<BalancerSwaps> {
const timeout = new Promise<BalancerSwaps>(resolve => setTimeout(resolve, timeoutMs, []));
return Promise.race([this._getAndSaveFreshSwapInfoForPairAsync(takerToken, makerToken), timeout]);
}
public getCachedSwapInfoForPair(
takerToken: string,
makerToken: string,
ignoreExpired: boolean = true,
): BalancerSwaps | undefined {
const key = JSON.stringify([takerToken, makerToken]);
const value = this._cache[key];
if (ignoreExpired) {
return value === undefined ? EMPTY_BALANCER_SWAPS : value.balancerSwaps;
}
if (!value) {
return undefined;
}
if (SwapInfoCache._isExpired(value)) {
return undefined;
}
return value.balancerSwaps;
}
public isFresh(takerToken: string, makerToken: string): boolean {
const cached = this.getCachedSwapInfoForPair(takerToken, makerToken, false);
return cached !== undefined;
}
protected async _getAndSaveFreshSwapInfoForPairAsync(
takerToken: string,
makerToken: string,
): Promise<BalancerSwaps> {
const key = JSON.stringify([takerToken, makerToken]);
const value = this._cache[key];
if (value === undefined || value.expiresAt >= Date.now()) {
const swapInfo = await this._fetchSwapInfoForPairAsync(takerToken, makerToken);
const expiresAt = Date.now() + this._cacheTimeMs;
this._cacheSwapInfoForPair(takerToken, makerToken, swapInfo, expiresAt);
}
return this._cache[key].balancerSwaps;
}
protected _cacheSwapInfoForPair(
takerToken: string,
makerToken: string,
swapInfo: BalancerSwaps,
expiresAt: number,
): void {
const key = JSON.stringify([takerToken, makerToken]);
this._cache[key] = {
expiresAt,
balancerSwaps: swapInfo,
};
}
protected abstract _fetchSwapInfoForPairAsync(takerToken: string, makerToken: string): Promise<BalancerSwaps>;
}

View File

@@ -0,0 +1,114 @@
import { ChainId } from '@0x/contract-addresses';
import { logUtils } from '@0x/utils';
import { PoolDataService, SubgraphPoolBase } from '@balancer-labs/sdk';
import { gql, request } from 'graphql-request';
const queryWithLinear = gql`
query fetchTopPoolsWithLinear($maxPoolsFetched: Int!) {
pools: pools(
first: $maxPoolsFetched
where: { swapEnabled: true }
orderBy: totalLiquidity
orderDirection: desc
) {
id
address
poolType
swapFee
totalShares
tokens {
address
balance
decimals
weight
priceRate
}
tokensList
totalWeight
amp
expiryTime
unitSeconds
principalToken
baseToken
swapEnabled
wrappedIndex
mainIndex
lowerTarget
upperTarget
}
}
`;
const queryWithOutLinear = gql`
query fetchTopPoolsWithoutLinear($maxPoolsFetched: Int!) {
pools: pools(
first: $maxPoolsFetched
where: { swapEnabled: true }
orderBy: totalLiquidity
orderDirection: desc
) {
id
address
poolType
swapFee
totalShares
tokens {
address
balance
decimals
weight
priceRate
}
tokensList
totalWeight
amp
expiryTime
unitSeconds
principalToken
baseToken
swapEnabled
}
}
`;
const QUERY_BY_CHAIN_ID: { [chainId: number]: string } = {
[ChainId.Mainnet]: queryWithLinear,
[ChainId.Polygon]: queryWithOutLinear,
};
const DEFAULT_MAX_POOLS_FETCHED = 96;
/**
* Simple service to query required info from Subgraph for Balancer Pools.
* Because Balancer Subgraphs have slightly different schema depending on network the queries are adjusted as needed.
*/
export class SubgraphPoolDataService implements PoolDataService {
private readonly _gqlQuery: string | undefined;
constructor(
private readonly _config: {
chainId: number;
subgraphUrl: string | null;
maxPoolsFetched?: number;
},
) {
this._config.maxPoolsFetched = this._config.maxPoolsFetched || DEFAULT_MAX_POOLS_FETCHED;
this._gqlQuery = QUERY_BY_CHAIN_ID[this._config.chainId];
}
// tslint:disable-next-line: async-suffix
public async getPools(): Promise<SubgraphPoolBase[]> {
if (!this._gqlQuery || !this._config.subgraphUrl) {
return [];
}
try {
const { pools } = await request<{ pools: SubgraphPoolBase[] }>(this._config.subgraphUrl, this._gqlQuery, {
maxPoolsFetched: this._config.maxPoolsFetched,
});
return pools;
} catch (err) {
logUtils.warn(`Failed to fetch BalancerV2 subgraph pools: ${err.message}`);
return [];
}
}
}

View File

@@ -5,9 +5,8 @@ import { SamplerOverrides } from '../../types';
import { ERC20BridgeSamplerContract } from '../../wrappers';
import { BancorService } from './bancor_service';
import { PoolsCache } from './pools_cache';
import { SamplerOperations } from './sampler_operations';
import { BatchedOperation, ERC20BridgeSource, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
import { PoolsCacheMap, SamplerOperations } from './sampler_operations';
import { BatchedOperation, LiquidityProviderRegistry, TokenAdjacencyGraph } from './types';
/**
* Generate sample amounts up to `maxFillAmount`.
@@ -37,7 +36,7 @@ export class DexOrderSampler extends SamplerOperations {
public readonly chainId: ChainId,
_samplerContract: ERC20BridgeSamplerContract,
private readonly _samplerOverrides?: SamplerOverrides,
poolsCaches?: { [key in ERC20BridgeSource]: PoolsCache },
poolsCaches?: PoolsCacheMap,
tokenAdjacencyGraph?: TokenAdjacencyGraph,
liquidityProviderRegistry?: LiquidityProviderRegistry,
bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,

View File

@@ -4,6 +4,7 @@ import { BigNumber, logUtils } from '@0x/utils';
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';
@@ -46,9 +47,11 @@ import {
UNISWAPV3_CONFIG_BY_CHAIN_ID,
ZERO_AMOUNT,
} from './constants';
import { getGeistInfoForPair } from './geist_utils';
import { getLiquidityProvidersForPair } from './liquidity_provider_utils';
import { getIntermediateTokens } from './multihop_utils';
import { BalancerPoolsCache, BalancerV2PoolsCache, CreamPoolsCache, PoolsCache } from './pools_cache';
import { BalancerV2SwapInfoCache } from './pools_cache/balancer_v2_utils_new';
import { SamplerContractOperation } from './sampler_contract_operation';
import { SamplerNoOperation } from './sampler_no_operation';
import { SourceFilters } from './source_filters';
@@ -56,6 +59,8 @@ import {
AaveV2FillData,
AaveV2Info,
BalancerFillData,
BalancerSwapInfo,
BalancerV2BatchSwapFillData,
BalancerV2FillData,
BalancerV2PoolInfo,
BancorFillData,
@@ -66,6 +71,8 @@ import {
DexSample,
DODOFillData,
ERC20BridgeSource,
GeistFillData,
GeistInfo,
GenericRouterFillData,
HopInfo,
KyberDmmFillData,
@@ -99,6 +106,10 @@ export const TWO_HOP_SOURCE_FILTERS = SourceFilters.all().exclude([
*/
export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSource.MultiHop, ERC20BridgeSource.Native]);
export type PoolsCacheMap = { [key in Exclude<SourcesWithPoolsCache, ERC20BridgeSource.BalancerV2>]: PoolsCache } & {
[ERC20BridgeSource.BalancerV2]: BalancerV2SwapInfoCache | undefined;
};
// tslint:disable:no-inferred-empty-object-type no-unbound-method
/**
@@ -107,7 +118,7 @@ export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSour
*/
export class SamplerOperations {
public readonly liquidityProviderRegistry: LiquidityProviderRegistry;
public readonly poolsCaches: { [key in SourcesWithPoolsCache]: PoolsCache };
public readonly poolsCaches: PoolsCacheMap;
public readonly aaveReservesCache: AaveV2ReservesCache | undefined;
public readonly compoundCTokenCache: CompoundCTokenCache | undefined;
protected _bancorService?: BancorService;
@@ -122,7 +133,7 @@ export class SamplerOperations {
constructor(
public readonly chainId: ChainId,
protected readonly _samplerContract: ERC20BridgeSamplerContract,
poolsCaches?: { [key in SourcesWithPoolsCache]: PoolsCache },
poolsCaches?: PoolsCacheMap,
protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] },
liquidityProviderRegistry: LiquidityProviderRegistry = {},
bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
@@ -134,13 +145,16 @@ export class SamplerOperations {
this.poolsCaches = poolsCaches
? poolsCaches
: {
[ERC20BridgeSource.BalancerV2]: new BalancerV2PoolsCache(chainId),
[ERC20BridgeSource.Beethovenx]: new BalancerV2PoolsCache(
chainId,
BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN[chainId],
),
[ERC20BridgeSource.Balancer]: new BalancerPoolsCache(),
[ERC20BridgeSource.Cream]: new CreamPoolsCache(),
[ERC20BridgeSource.BalancerV2]:
BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[chainId] === NULL_ADDRESS
? undefined
: new BalancerV2SwapInfoCache(chainId),
};
const aaveSubgraphUrl = AAVE_V2_SUBGRAPH_URL_BY_CHAIN_ID[chainId];
@@ -560,6 +574,49 @@ export class SamplerOperations {
});
}
public getBalancerV2MultihopSellQuotes(
vault: string,
quoteSwaps: BalancerSwapInfo, // Should always be sell swap steps.
fillSwaps: BalancerSwapInfo, // Should always be sell swap steps.
takerFillAmounts: BigNumber[],
source: ERC20BridgeSource,
): SourceQuoteOperation<BalancerV2BatchSwapFillData> {
const quoteSwapSteps = quoteSwaps.swapSteps.map(s => ({
...s,
assetInIndex: new BigNumber(s.assetInIndex),
assetOutIndex: new BigNumber(s.assetOutIndex),
}));
return new SamplerContractOperation({
source,
fillData: { vault, swapSteps: fillSwaps.swapSteps, assets: fillSwaps.assets },
contract: this._samplerContract,
function: this._samplerContract.sampleMultihopSellsFromBalancerV2,
params: [vault, quoteSwapSteps, quoteSwaps.assets, takerFillAmounts],
});
}
public getBalancerV2MultihopBuyQuotes(
vault: string,
quoteSwaps: BalancerSwapInfo, // Should always be buy swap steps.
fillSwaps: BalancerSwapInfo, // Should always be a sell quote.
makerFillAmounts: BigNumber[],
source: ERC20BridgeSource,
): SourceQuoteOperation<BalancerV2BatchSwapFillData> {
const quoteSwapSteps = quoteSwaps.swapSteps.map(s => ({
...s,
assetInIndex: new BigNumber(s.assetInIndex),
assetOutIndex: new BigNumber(s.assetOutIndex),
}));
return new SamplerContractOperation({
source,
// NOTE: fillData is set up for sells but quote function is set up for buys.
fillData: { vault, swapSteps: fillSwaps.swapSteps, assets: fillSwaps.assets },
contract: this._samplerContract,
function: this._samplerContract.sampleMultihopBuysFromBalancerV2,
params: [vault, quoteSwapSteps, quoteSwaps.assets, makerFillAmounts],
});
}
public getBalancerV2SellQuotes(
poolInfo: BalancerV2PoolInfo,
makerToken: string,
@@ -767,16 +824,17 @@ export class SamplerOperations {
function: this._samplerContract.sampleSellsFromUniswapV3,
params: [quoter, tokenAddressPath, takerFillAmounts],
callback: (callResults: string, fillData: UniswapV3FillData): BigNumber[] => {
const [paths, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>(
'sampleSellsFromUniswapV3',
callResults,
);
const [paths, gasUsed, samples] = this._samplerContract.getABIDecodedReturnData<
[string[], BigNumber[], BigNumber[]]
>('sampleSellsFromUniswapV3', callResults);
fillData.router = router;
fillData.tokenAddressPath = tokenAddressPath;
fillData.pathAmounts = paths.map((uniswapPath, i) => ({
uniswapPath,
inputAmount: takerFillAmounts[i],
gasUsed: gasUsed[i].toNumber(),
}));
return samples;
},
});
@@ -795,15 +853,15 @@ export class SamplerOperations {
function: this._samplerContract.sampleBuysFromUniswapV3,
params: [quoter, tokenAddressPath, makerFillAmounts],
callback: (callResults: string, fillData: UniswapV3FillData): BigNumber[] => {
const [paths, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>(
'sampleBuysFromUniswapV3',
callResults,
);
const [paths, gasUsed, samples] = this._samplerContract.getABIDecodedReturnData<
[string[], BigNumber[], BigNumber[]]
>('sampleBuysFromUniswapV3', callResults);
fillData.router = router;
fillData.tokenAddressPath = tokenAddressPath;
fillData.pathAmounts = paths.map((uniswapPath, i) => ({
uniswapPath,
inputAmount: makerFillAmounts[i],
gasUsed: gasUsed[i].toNumber(),
}));
return samples;
},
@@ -1151,6 +1209,34 @@ export class SamplerOperations {
});
}
// tslint:disable-next-line:prefer-function-over-method
public getGeistSellQuotes(
geistInfo: GeistInfo,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
): SourceQuoteOperation<GeistFillData> {
return new SamplerNoOperation({
source: ERC20BridgeSource.Geist,
fillData: { ...geistInfo, takerToken },
callback: () => GeistSampler.sampleSellsFromGeist(geistInfo, takerToken, makerToken, takerFillAmounts),
});
}
// tslint:disable-next-line:prefer-function-over-method
public getGeistBuyQuotes(
geistInfo: GeistInfo,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<GeistFillData> {
return new SamplerNoOperation({
source: ERC20BridgeSource.Geist,
fillData: { ...geistInfo, takerToken },
callback: () => GeistSampler.sampleBuysFromGeist(geistInfo, takerToken, makerToken, makerFillAmounts),
});
}
public getCompoundSellQuotes(
cToken: string,
makerToken: string,
@@ -1350,6 +1436,7 @@ export class SamplerOperations {
case ERC20BridgeSource.FirebirdOneSwap:
case ERC20BridgeSource.IronSwap:
case ERC20BridgeSource.ACryptos:
case ERC20BridgeSource.MobiusMoney:
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
this.getCurveSellQuotes(
pool,
@@ -1414,15 +1501,27 @@ export class SamplerOperations {
ERC20BridgeSource.Balancer,
),
);
case ERC20BridgeSource.BalancerV2:
case ERC20BridgeSource.Beethovenx:
case ERC20BridgeSource.BalancerV2: {
const cache = this.poolsCaches[source];
if (!cache) {
return [];
}
const swaps = cache.getCachedSwapInfoForPair(takerToken, makerToken);
const vault = BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId];
if (!swaps || vault === NULL_ADDRESS) {
return [];
}
// Changed to retrieve queryBatchSwap for swap steps > 1 of length
return swaps.swapInfoExactIn.map(swapInfo =>
this.getBalancerV2MultihopSellQuotes(vault, swapInfo, swapInfo, takerFillAmounts, source),
);
}
case ERC20BridgeSource.Beethovenx: {
const poolIds =
this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
const vault =
source === ERC20BridgeSource.BalancerV2
? BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId]
: BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
const vault = BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
if (vault === NULL_ADDRESS) {
return [];
}
@@ -1435,6 +1534,7 @@ export class SamplerOperations {
source,
),
);
}
case ERC20BridgeSource.Cream:
return (
this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
@@ -1548,6 +1648,13 @@ export class SamplerOperations {
};
return this.getAaveV2SellQuotes(info, makerToken, takerToken, takerFillAmounts);
}
case ERC20BridgeSource.Geist: {
const info: GeistInfo | undefined = getGeistInfoForPair(takerToken, makerToken);
if (!info) {
return [];
}
return this.getGeistSellQuotes(info, makerToken, takerToken, takerFillAmounts);
}
case ERC20BridgeSource.Compound: {
if (!this.compoundCTokenCache) {
return [];
@@ -1578,7 +1685,7 @@ export class SamplerOperations {
takerToken: string,
makerFillAmounts: BigNumber[],
): SourceQuoteOperation[] {
// Find the adjacent tokens in the provided tooken adjacency graph,
// Find the adjacent tokens in the provided token adjacency graph,
// e.g if this is DAI->USDC we may check for DAI->WETH->USDC
const intermediateTokens = getIntermediateTokens(makerToken, takerToken, this.tokenAdjacencyGraph);
const _sources = BATCH_SOURCE_FILTERS.getAllowed(sources);
@@ -1656,6 +1763,7 @@ export class SamplerOperations {
case ERC20BridgeSource.FirebirdOneSwap:
case ERC20BridgeSource.IronSwap:
case ERC20BridgeSource.ACryptos:
case ERC20BridgeSource.MobiusMoney:
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
this.getCurveBuyQuotes(
pool,
@@ -1720,15 +1828,33 @@ export class SamplerOperations {
ERC20BridgeSource.Balancer,
),
);
case ERC20BridgeSource.BalancerV2:
case ERC20BridgeSource.Beethovenx:
case ERC20BridgeSource.BalancerV2: {
const cache = this.poolsCaches[source];
if (!cache) {
return [];
}
const swaps = cache.getCachedSwapInfoForPair(takerToken, makerToken);
const vault = BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId];
if (!swaps || vault === NULL_ADDRESS) {
return [];
}
// Changed to retrieve queryBatchSwap for swap steps > 1 of length
return swaps.swapInfoExactOut.map((quoteSwapInfo, i) =>
this.getBalancerV2MultihopBuyQuotes(
vault,
quoteSwapInfo,
swaps.swapInfoExactIn[i],
makerFillAmounts,
source,
),
);
}
case ERC20BridgeSource.Beethovenx: {
const poolIds =
this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
const vault =
source === ERC20BridgeSource.BalancerV2
? BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId]
: BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
const vault = BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
if (vault === NULL_ADDRESS) {
return [];
}
@@ -1741,6 +1867,7 @@ export class SamplerOperations {
source,
),
);
}
case ERC20BridgeSource.Cream:
return (
this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
@@ -1849,6 +1976,13 @@ export class SamplerOperations {
};
return this.getAaveV2BuyQuotes(info, makerToken, takerToken, makerFillAmounts);
}
case ERC20BridgeSource.Geist: {
const info: GeistInfo | undefined = getGeistInfoForPair(takerToken, makerToken);
if (!info) {
return [];
}
return this.getGeistBuyQuotes(info, makerToken, takerToken, makerFillAmounts);
}
case ERC20BridgeSource.Compound: {
if (!this.compoundCTokenCache) {
return [];

View File

@@ -10,7 +10,6 @@ import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts }
import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor';
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator';
import { CollapsedPath } from './path';
import { SourceFilters } from './source_filters';
/**
@@ -97,11 +96,13 @@ export enum ERC20BridgeSource {
TraderJoe = 'TraderJoe',
// Celo only
UbeSwap = 'UbeSwap',
MobiusMoney = 'MobiusMoney',
// Fantom
SpiritSwap = 'SpiritSwap',
SpookySwap = 'SpookySwap',
Beethovenx = 'Beethovenx',
MorpheusSwap = 'MorpheusSwap',
Geist = 'Geist',
}
export type SourcesWithPoolsCache =
| ERC20BridgeSource.Balancer
@@ -181,6 +182,12 @@ export interface AaveV2Info {
underlyingToken: string;
}
export interface GeistInfo {
lendingPool: string;
gToken: string;
underlyingToken: string;
}
// Internal `fillData` field for `Fill` objects.
export interface FillData {}
@@ -202,6 +209,23 @@ export interface CurveFillData extends FillData {
pool: CurveInfo;
}
export interface BalancerBatchSwapStep {
poolId: string;
assetInIndex: number;
assetOutIndex: number;
amount: BigNumber;
userData: string;
}
export interface BalancerSwaps {
swapInfoExactIn: BalancerSwapInfo[];
swapInfoExactOut: BalancerSwapInfo[];
}
export interface BalancerSwapInfo {
assets: string[];
swapSteps: BalancerBatchSwapStep[];
}
export interface BalancerFillData extends FillData {
poolAddress: string;
}
@@ -211,6 +235,12 @@ export interface BalancerV2FillData extends FillData {
poolId: string;
}
export interface BalancerV2BatchSwapFillData extends FillData {
vault: string;
swapSteps: BalancerBatchSwapStep[];
assets: string[];
}
export interface UniswapV2FillData extends FillData {
tokenAddressPath: string[];
router: string;
@@ -268,19 +298,34 @@ export interface HopInfo {
returnData: string;
}
export interface UniswapV3PathAmount {
uniswapPath: string;
inputAmount: BigNumber;
gasUsed: number;
}
export interface UniswapV3FillData extends FillData {
tokenAddressPath: string[];
router: string;
pathAmounts: Array<{ uniswapPath: string; inputAmount: BigNumber }>;
pathAmounts: UniswapV3PathAmount[];
}
export interface KyberDmmFillData extends UniswapV2FillData {
poolsPath: string[];
}
export interface FinalUniswapV3FillData extends Omit<UniswapV3FillData, 'uniswapPaths'> {
/**
* Determines whether FillData is UniswapV3FillData or FinalUniswapV3FillData
*/
export function isFinalUniswapV3FillData(
data: UniswapV3FillData | FinalUniswapV3FillData,
): data is FinalUniswapV3FillData {
return !!(data as FinalUniswapV3FillData).uniswapPath;
}
export interface FinalUniswapV3FillData extends Omit<UniswapV3FillData, 'pathAmounts'> {
// The uniswap-encoded path that can fll the maximum input amount.
uniswapPath: string;
gasUsed: number;
}
export interface LidoFillData extends FillData {
@@ -301,6 +346,13 @@ export interface CompoundFillData extends FillData {
makerToken: string;
}
export interface GeistFillData extends FillData {
lendingPool: string;
gToken: string;
underlyingToken: string;
takerToken: string;
}
/**
* Represents a node on a fill path.
*/
@@ -550,7 +602,6 @@ export interface OptimizerResult {
liquidityDelivered: CollapsedFill[] | DexSample<MultiHopFillData>;
marketSideLiquidity: MarketSideLiquidity;
adjustedRate: BigNumber;
unoptimizedPath?: CollapsedPath;
takerAmountPerEth: BigNumber;
makerAmountPerEth: BigNumber;
}
@@ -582,6 +633,7 @@ export interface MarketSideLiquidity {
takerTokenDecimals: number;
quotes: RawQuotes;
isRfqSupported: boolean;
blockNumber: number;
}
export interface RawQuotes {

View File

@@ -106,6 +106,8 @@ export interface ExtendedQuoteReport {
decodedUniqueId?: string;
sourcesConsidered: ExtendedQuoteReportIndexedEntryOutbound[];
sourcesDelivered: ExtendedQuoteReportIndexedEntryOutbound[] | undefined;
blockNumber: number | undefined;
estimatedGas: string;
}
export interface PriceComparisonsReport {
@@ -205,7 +207,7 @@ export function generateExtendedQuoteReportSources(
..._.flatten(
quotes.dexQuotes.map(dex =>
dex
.filter(quote => isDexSampleForTotalAmount(quote, marketOperation, amount))
.filter(quote => isDexSampleForTotalAmount(quote, amount))
.map(quote => dexSampleToReportSource(quote, marketOperation)),
),
),
@@ -304,16 +306,8 @@ export function dexSampleToReportSource(ds: DexSample, marketOperation: MarketOp
* Checks if a DEX sample is the one that represents the whole amount requested by taker
* NOTE: this is used for the QuoteReport to filter samples
*/
function isDexSampleForTotalAmount(ds: DexSample, marketOperation: MarketOperation, amount: BigNumber): boolean {
// input and output map to different values
// based on the market operation
if (marketOperation === MarketOperation.Buy) {
return ds.input === amount;
} else if (marketOperation === MarketOperation.Sell) {
return ds.output === amount;
} else {
throw new Error(`Unexpected marketOperation ${marketOperation}`);
}
function isDexSampleForTotalAmount(ds: DexSample, amount: BigNumber): boolean {
return ds.input.eq(amount);
}
/**

View File

@@ -8,16 +8,18 @@ import { ContractArtifact } from 'ethereum-types';
import * as ApproximateBuys from '../test/generated-artifacts/ApproximateBuys.json';
import * as BalanceChecker from '../test/generated-artifacts/BalanceChecker.json';
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.json';
import * as BalancerV2BatchSampler from '../test/generated-artifacts/BalancerV2BatchSampler.json';
import * as BalancerV2Common from '../test/generated-artifacts/BalancerV2Common.json';
import * as BalancerV2Sampler from '../test/generated-artifacts/BalancerV2Sampler.json';
import * as BancorSampler from '../test/generated-artifacts/BancorSampler.json';
import * as CompoundSampler from '../test/generated-artifacts/CompoundSampler.json';
import * as CurveSampler from '../test/generated-artifacts/CurveSampler.json';
import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json';
import * as DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json';
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
import * as FakeTaker from '../test/generated-artifacts/FakeTaker.json';
import * as IBalancer from '../test/generated-artifacts/IBalancer.json';
import * as IBalancerV2Vault from '../test/generated-artifacts/IBalancerV2Vault.json';
import * as IBancor from '../test/generated-artifacts/IBancor.json';
import * as ICurve from '../test/generated-artifacts/ICurve.json';
import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json';
@@ -35,12 +37,10 @@ import * as LiquidityProviderSampler from '../test/generated-artifacts/Liquidity
import * as MakerPSMSampler from '../test/generated-artifacts/MakerPSMSampler.json';
import * as MooniswapSampler from '../test/generated-artifacts/MooniswapSampler.json';
import * as MStableSampler from '../test/generated-artifacts/MStableSampler.json';
import * as MultiBridgeSampler from '../test/generated-artifacts/MultiBridgeSampler.json';
import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json';
import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json';
import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json';
import * as SmoothySampler from '../test/generated-artifacts/SmoothySampler.json';
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
import * as TestNativeOrderSampler from '../test/generated-artifacts/TestNativeOrderSampler.json';
import * as TwoHopSampler from '../test/generated-artifacts/TwoHopSampler.json';
import * as UniswapSampler from '../test/generated-artifacts/UniswapSampler.json';
@@ -51,6 +51,8 @@ export const artifacts = {
ApproximateBuys: ApproximateBuys as ContractArtifact,
BalanceChecker: BalanceChecker as ContractArtifact,
BalancerSampler: BalancerSampler as ContractArtifact,
BalancerV2BatchSampler: BalancerV2BatchSampler as ContractArtifact,
BalancerV2Common: BalancerV2Common as ContractArtifact,
BalancerV2Sampler: BalancerV2Sampler as ContractArtifact,
BancorSampler: BancorSampler as ContractArtifact,
CompoundSampler: CompoundSampler as ContractArtifact,
@@ -66,7 +68,6 @@ export const artifacts = {
MStableSampler: MStableSampler as ContractArtifact,
MakerPSMSampler: MakerPSMSampler as ContractArtifact,
MooniswapSampler: MooniswapSampler as ContractArtifact,
MultiBridgeSampler: MultiBridgeSampler as ContractArtifact,
NativeOrderSampler: NativeOrderSampler as ContractArtifact,
SamplerUtils: SamplerUtils as ContractArtifact,
ShellSampler: ShellSampler as ContractArtifact,
@@ -77,6 +78,7 @@ export const artifacts = {
UniswapV3Sampler: UniswapV3Sampler as ContractArtifact,
UtilitySampler: UtilitySampler as ContractArtifact,
IBalancer: IBalancer as ContractArtifact,
IBalancerV2Vault: IBalancerV2Vault as ContractArtifact,
IBancor: IBancor as ContractArtifact,
ICurve: ICurve as ContractArtifact,
IKyberNetwork: IKyberNetwork as ContractArtifact,
@@ -87,7 +89,5 @@ export const artifacts = {
ISmoothy: ISmoothy as ContractArtifact,
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact,
DummyLiquidityProvider: DummyLiquidityProvider as ContractArtifact,
TestERC20BridgeSampler: TestERC20BridgeSampler as ContractArtifact,
TestNativeOrderSampler: TestNativeOrderSampler as ContractArtifact,
};

View File

@@ -66,6 +66,7 @@ const buyMarketSideLiquidity: MarketSideLiquidity = {
},
quoteSourceFilters: new SourceFilters(),
isRfqSupported: false,
blockNumber: 1337420,
};
const sellMarketSideLiquidity: MarketSideLiquidity = {
@@ -87,6 +88,7 @@ const sellMarketSideLiquidity: MarketSideLiquidity = {
},
quoteSourceFilters: new SourceFilters(),
isRfqSupported: false,
blockNumber: 1337420,
};
describe('getComparisonPrices', async () => {

View File

@@ -141,6 +141,7 @@ describe('ExchangeProxySwapQuoteConsumer', () => {
...(side === MarketOperation.Buy
? { type: MarketOperation.Buy, makerTokenFillAmount }
: { type: MarketOperation.Sell, takerTokenFillAmount }),
blockNumber: 1337420,
};
}

View File

@@ -483,7 +483,8 @@ describe('MarketOperationUtils tests', () => {
});
it('queries `numSamples` samples', async () => {
const numSamples = _.random(1, NUM_SAMPLES);
// neon-router requires at least 3 samples
const numSamples = _.random(3, NUM_SAMPLES);
let actualNumSamples = 0;
replaceSamplerOps({
getSellQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
@@ -501,6 +502,7 @@ describe('MarketOperationUtils tests', () => {
await getMarketSellOrdersAsync(marketOperationUtils, ORDERS, FILL_AMOUNT, {
...DEFAULT_OPTS,
numSamples,
neonRouterNumSamples: numSamples,
});
expect(actualNumSamples).eq(numSamples);
});
@@ -746,6 +748,7 @@ describe('MarketOperationUtils tests', () => {
],
},
isRfqSupported: true,
blockNumber: 1337420,
};
});
const result = await mockedMarketOpUtils.object.getOptimizerResultAsync(
@@ -1078,7 +1081,8 @@ describe('MarketOperationUtils tests', () => {
const ETH_TO_MAKER_RATE = 1.5;
it('factors in fees for native orders', async () => {
// TODO: disabled as this is not supported by neon-router
it.skip('factors in fees for native orders', async () => {
// Native orders will have the best rates but have fees,
// dropping their effective rates.
const nativeFeeRate = 0.06;
@@ -1181,7 +1185,9 @@ describe('MarketOperationUtils tests', () => {
expect(orderSources.sort()).to.deep.eq(expectedSources.sort());
});
it('does not create a fallback if below maxFallbackSlippage', async () => {
// NOTE: Currently fallbacks for native orders are disabled
// TODO: remove this if we remove fallbacks completely
it.skip('does not create a fallback if below maxFallbackSlippage', async () => {
const rates: RatesBySource = {};
rates[ERC20BridgeSource.Native] = [1, 1, 0.01, 0.01];
rates[ERC20BridgeSource.Uniswap] = [1, 1, 0.01, 0.01];
@@ -1325,7 +1331,8 @@ describe('MarketOperationUtils tests', () => {
});
it('queries `numSamples` samples', async () => {
const numSamples = _.random(1, 16);
// neon-router requires at least 3 samples
const numSamples = _.random(3, 16);
let actualNumSamples = 0;
replaceSamplerOps({
getBuyQuotes: (sources, makerToken, takerToken, amounts, wethAddress) => {
@@ -1343,6 +1350,8 @@ describe('MarketOperationUtils tests', () => {
await getMarketBuyOrdersAsync(marketOperationUtils, ORDERS, FILL_AMOUNT, {
...DEFAULT_OPTS,
numSamples,
// Make sure to use same number of samples in neon-router for compatibility
neonRouterNumSamples: numSamples,
});
expect(actualNumSamples).eq(numSamples);
});
@@ -1494,7 +1503,8 @@ describe('MarketOperationUtils tests', () => {
}
});
it('can mix convex sources', async () => {
// TODO: disabled as this is not supported by neon-router
it.skip('can mix convex sources', async () => {
const rates: RatesBySource = { ...ZERO_RATES };
rates[ERC20BridgeSource.Native] = [0.4, 0.3, 0.2, 0.1];
rates[ERC20BridgeSource.Uniswap] = [0.5, 0.05, 0.05, 0.05];
@@ -1521,7 +1531,8 @@ describe('MarketOperationUtils tests', () => {
const ETH_TO_TAKER_RATE = 1.5;
it('factors in fees for native orders', async () => {
// TODO: disabled as this is not supported by neon-router
it.skip('factors in fees for native orders', async () => {
// Native orders will have the best rates but have fees,
// dropping their effective rates.
const nativeFeeRate = 0.06;
@@ -1598,7 +1609,9 @@ describe('MarketOperationUtils tests', () => {
expect(orderSources.sort()).to.deep.eq(expectedSources.sort());
});
it('does not create a fallback if below maxFallbackSlippage', async () => {
// NOTE: Currently fallbacks for native orders are disabled
// TODO: remove this if we remove fallbacks completely
it.skip('does not create a fallback if below maxFallbackSlippage', async () => {
const rates: RatesBySource = { ...ZERO_RATES };
rates[ERC20BridgeSource.Native] = [1, 1, 0.01, 0.01];
rates[ERC20BridgeSource.Uniswap] = [1, 1, 0.01, 0.01];

View File

@@ -44,6 +44,7 @@ export async function getFullyFillableSwapQuoteWithNoFeesAsync(
makerAmountPerEth: constants.ZERO_AMOUNT,
makerTokenDecimals: 18,
takerTokenDecimals: 18,
blockNumber: 1337420,
};
if (operation === MarketOperation.Buy) {

View File

@@ -6,16 +6,18 @@
export * from '../test/generated-wrappers/approximate_buys';
export * from '../test/generated-wrappers/balance_checker';
export * from '../test/generated-wrappers/balancer_sampler';
export * from '../test/generated-wrappers/balancer_v2_batch_sampler';
export * from '../test/generated-wrappers/balancer_v2_common';
export * from '../test/generated-wrappers/balancer_v2_sampler';
export * from '../test/generated-wrappers/bancor_sampler';
export * from '../test/generated-wrappers/compound_sampler';
export * from '../test/generated-wrappers/curve_sampler';
export * from '../test/generated-wrappers/d_o_d_o_sampler';
export * from '../test/generated-wrappers/d_o_d_o_v2_sampler';
export * from '../test/generated-wrappers/dummy_liquidity_provider';
export * from '../test/generated-wrappers/erc20_bridge_sampler';
export * from '../test/generated-wrappers/fake_taker';
export * from '../test/generated-wrappers/i_balancer';
export * from '../test/generated-wrappers/i_balancer_v2_vault';
export * from '../test/generated-wrappers/i_bancor';
export * from '../test/generated-wrappers/i_curve';
export * from '../test/generated-wrappers/i_kyber_network';
@@ -33,12 +35,10 @@ export * from '../test/generated-wrappers/liquidity_provider_sampler';
export * from '../test/generated-wrappers/m_stable_sampler';
export * from '../test/generated-wrappers/maker_p_s_m_sampler';
export * from '../test/generated-wrappers/mooniswap_sampler';
export * from '../test/generated-wrappers/multi_bridge_sampler';
export * from '../test/generated-wrappers/native_order_sampler';
export * from '../test/generated-wrappers/sampler_utils';
export * from '../test/generated-wrappers/shell_sampler';
export * from '../test/generated-wrappers/smoothy_sampler';
export * from '../test/generated-wrappers/test_erc20_bridge_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';

View File

@@ -9,16 +9,18 @@
"test/generated-artifacts/ApproximateBuys.json",
"test/generated-artifacts/BalanceChecker.json",
"test/generated-artifacts/BalancerSampler.json",
"test/generated-artifacts/BalancerV2BatchSampler.json",
"test/generated-artifacts/BalancerV2Common.json",
"test/generated-artifacts/BalancerV2Sampler.json",
"test/generated-artifacts/BancorSampler.json",
"test/generated-artifacts/CompoundSampler.json",
"test/generated-artifacts/CurveSampler.json",
"test/generated-artifacts/DODOSampler.json",
"test/generated-artifacts/DODOV2Sampler.json",
"test/generated-artifacts/DummyLiquidityProvider.json",
"test/generated-artifacts/ERC20BridgeSampler.json",
"test/generated-artifacts/FakeTaker.json",
"test/generated-artifacts/IBalancer.json",
"test/generated-artifacts/IBalancerV2Vault.json",
"test/generated-artifacts/IBancor.json",
"test/generated-artifacts/ICurve.json",
"test/generated-artifacts/IKyberNetwork.json",
@@ -36,12 +38,10 @@
"test/generated-artifacts/MStableSampler.json",
"test/generated-artifacts/MakerPSMSampler.json",
"test/generated-artifacts/MooniswapSampler.json",
"test/generated-artifacts/MultiBridgeSampler.json",
"test/generated-artifacts/NativeOrderSampler.json",
"test/generated-artifacts/SamplerUtils.json",
"test/generated-artifacts/ShellSampler.json",
"test/generated-artifacts/SmoothySampler.json",
"test/generated-artifacts/TestERC20BridgeSampler.json",
"test/generated-artifacts/TestNativeOrderSampler.json",
"test/generated-artifacts/TwoHopSampler.json",
"test/generated-artifacts/UniswapSampler.json",

View File

@@ -1,4 +1,33 @@
[
{
"version": "6.13.0",
"changes": [
{
"note": "Redeploy FQT on mainnet and polygon",
"pr": 462
}
],
"timestamp": 1650611093
},
{
"timestamp": 1648739346,
"version": "6.12.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "6.12.0",
"changes": [
{
"note": "Update fantom fillQuoteTransformer addresses",
"pr": 398
}
],
"timestamp": 1646225739
},
{
"version": "6.11.0",
"changes": [

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v6.13.0 - _April 22, 2022_
* Redeploy FQT on mainnet and polygon (#462)
## v6.12.1 - _March 31, 2022_
* Dependencies updated
## v6.12.0 - _March 2, 2022_
* Update fantom fillQuoteTransformer addresses (#398)
## v6.11.0 - _December 24, 2021_
* Add Optimism addresses (#385)

View File

@@ -37,7 +37,7 @@
"wethTransformer": "0xb2bc06a4efb20fc6553a69dbfa49b7be938034a7",
"payTakerTransformer": "0x4638a7ebe75b911b995d0ec73a81e4f85f41f24e",
"affiliateFeeTransformer": "0xda6d9fc5998f550a094585cf9171f0e8ee3ac59f",
"fillQuoteTransformer": "0xb4fa284689c9784a60d840eb136bb16c5246191f",
"fillQuoteTransformer": "0xadbe39f2988a8be1c1120f05e28cc888b150c8a6",
"positiveSlippageFeeTransformer": "0xa9416ce1dbde8d331210c07b5c253d94ee4cc3fd"
}
},
@@ -289,7 +289,7 @@
"wethTransformer": "0xe309d011cc6f189a3e8dcba85922715a019fed38",
"payTakerTransformer": "0x5ba7b9be86cda01cfbf56e0fb97184783be9dda1",
"affiliateFeeTransformer": "0xbed27284b42e5684e987169cf1da09c5d6c49fa8",
"fillQuoteTransformer": "0xd3afdf4a8ea9183e76c9c2306cda03ea4afffea5",
"fillQuoteTransformer": "0xd4a518760030dae1adbde9496f8a3b478e83932a",
"positiveSlippageFeeTransformer": "0x4cd8f1c0df4d40fcc1e073845d5f6f4ed5cc8dab"
}
},
@@ -415,7 +415,7 @@
"wethTransformer": "0x9b6aa8f26a92108e7d1f66373d757bb955112703",
"payTakerTransformer": "0x32df54951d33d7460e15fa59b1fcc262183ce4c2",
"affiliateFeeTransformer": "0x67efa679a4b56c38713d478e649c88247f4f8e88",
"fillQuoteTransformer": "0x71de60a1b160094a3f6c7e1b883ff9337d639131",
"fillQuoteTransformer": "0x641efe8a57ad39353fe22f77d211ef6b17b0590b",
"positiveSlippageFeeTransformer": "0xe87d69b285005cc82b53b844322652c49ed64600"
}
},

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contract-addresses",
"version": "6.11.0",
"version": "6.13.0",
"engines": {
"node": ">=6.12"
},
@@ -30,7 +30,7 @@
"devDependencies": {
"gitpkg": "https://github.com/0xProject/gitpkg.git",
"shx": "^0.2.2",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,14 @@
[
{
"version": "3.18.0",
"changes": [
{
"note": "Regenerate all artifacts",
"pr": 449
}
],
"timestamp": 1648739346
},
{
"version": "3.17.0",
"changes": [

View File

@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.18.0 - _March 31, 2022_
* Regenerate all artifacts (#449)
## v3.17.0 - _February 22, 2022_
* Update IZeroEx artifact (#429)

File diff suppressed because one or more lines are too long

View File

@@ -135,10 +135,10 @@
},
"evm": {
"bytecode": {
"object": "0x608060405234801561001057600080fd5b506106bf806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806370a082311161005057806370a0823114610121578063a9059cbb14610154578063dd62ed3e1461018d57610072565b8063095ea7b31461007757806318160ddd146100c457806323b872dd146100de575b600080fd5b6100b06004803603604081101561008d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356101c8565b604080519115158252519081900360200190f35b6100cc61023b565b60408051918252519081900360200190f35b6100b0600480360360608110156100f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610241565b6100cc6004803603602081101561013757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661049d565b6100b06004803603604081101561016a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356104c5565b6100cc600480360360408110156101a357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610652565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60025490565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120548211156102d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482111561037457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45524332305f494e53554646494349454e545f414c4c4f57414e434500000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054828101101561040a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80841660008181526020818152604080832080548801905593881680835284832080548890039055600182528483203384528252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060019392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b3360009081526020819052604081205482111561054357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110156105d957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526001602090815260408083209390941682529190915220549056fea265627a7a723158200a0e5b4813b81b4a59cf323e9296dbdc12eadc2b35caf21c2052aa9fc5df88b364736f6c63430005110032"
"object": "0x608060405234801561001057600080fd5b506106bf806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806370a082311161005057806370a0823114610121578063a9059cbb14610154578063dd62ed3e1461018d57610072565b8063095ea7b31461007757806318160ddd146100c457806323b872dd146100de575b600080fd5b6100b06004803603604081101561008d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356101c8565b604080519115158252519081900360200190f35b6100cc61023b565b60408051918252519081900360200190f35b6100b0600480360360608110156100f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610241565b6100cc6004803603602081101561013757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661049d565b6100b06004803603604081101561016a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356104c5565b6100cc600480360360408110156101a357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610652565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60025490565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120548211156102d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482111561037457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45524332305f494e53554646494349454e545f414c4c4f57414e434500000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054828101101561040a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80841660008181526020818152604080832080548801905593881680835284832080548890039055600182528483203384528252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060019392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b3360009081526020819052604081205482111561054357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110156105d957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526001602090815260408083209390941682529190915220549056fea265627a7a72315820a51afc8c5cb32c94c3f05c807ed412c5091b6f59e504ef34013b272c3c46a3ee64736f6c63430005110032"
},
"deployedBytecode": {
"object": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c806370a082311161005057806370a0823114610121578063a9059cbb14610154578063dd62ed3e1461018d57610072565b8063095ea7b31461007757806318160ddd146100c457806323b872dd146100de575b600080fd5b6100b06004803603604081101561008d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356101c8565b604080519115158252519081900360200190f35b6100cc61023b565b60408051918252519081900360200190f35b6100b0600480360360608110156100f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610241565b6100cc6004803603602081101561013757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661049d565b6100b06004803603604081101561016a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356104c5565b6100cc600480360360408110156101a357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610652565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60025490565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120548211156102d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482111561037457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45524332305f494e53554646494349454e545f414c4c4f57414e434500000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054828101101561040a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80841660008181526020818152604080832080548801905593881680835284832080548890039055600182528483203384528252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060019392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b3360009081526020819052604081205482111561054357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110156105d957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526001602090815260408083209390941682529190915220549056fea265627a7a723158200a0e5b4813b81b4a59cf323e9296dbdc12eadc2b35caf21c2052aa9fc5df88b364736f6c63430005110032"
"object": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c806370a082311161005057806370a0823114610121578063a9059cbb14610154578063dd62ed3e1461018d57610072565b8063095ea7b31461007757806318160ddd146100c457806323b872dd146100de575b600080fd5b6100b06004803603604081101561008d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356101c8565b604080519115158252519081900360200190f35b6100cc61023b565b60408051918252519081900360200190f35b6100b0600480360360608110156100f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610241565b6100cc6004803603602081101561013757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661049d565b6100b06004803603604081101561016a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356104c5565b6100cc600480360360408110156101a357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610652565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60025490565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120548211156102d557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482111561037457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45524332305f494e53554646494349454e545f414c4c4f57414e434500000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054828101101561040a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80841660008181526020818152604080832080548801905593881680835284832080548890039055600182528483203384528252918490208054879003905583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35060019392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b3360009081526020819052604081205482111561054357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f45524332305f494e53554646494349454e545f42414c414e4345000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110156105d957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f55494e543235365f4f564552464c4f5700000000000000000000000000000000604482015290519081900360640190fd5b336000818152602081815260408083208054879003905573ffffffffffffffffffffffffffffffffffffffff871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526001602090815260408083209390941682529190915220549056fea265627a7a72315820a51afc8c5cb32c94c3f05c807ed412c5091b6f59e504ef34013b272c3c46a3ee64736f6c63430005110032"
}
}
},

View File

@@ -158,10 +158,10 @@
"devdoc": { "methods": {} },
"evm": {
"bytecode": {
"object": "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158206b7dcca2f4268299085314087a9c8506d18f6b6a5debabd331b75cf760e6714564736f6c63430005110032"
"object": "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158207b3f55a80647ba1c13f3619b5076feeeb78e1bd7df76cf334f47aa40f79b623864736f6c63430005110032"
},
"deployedBytecode": {
"object": "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158206b7dcca2f4268299085314087a9c8506d18f6b6a5debabd331b75cf760e6714564736f6c63430005110032"
"object": "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158207b3f55a80647ba1c13f3619b5076feeeb78e1bd7df76cf334f47aa40f79b623864736f6c63430005110032"
}
}
},

View File

@@ -125,10 +125,10 @@
},
"evm": {
"bytecode": {
"object": "0x60606040526b033b2e3c9fd0803ce8000000600355341561001c57fe5b5b600354600160a060020a0333166000908152602081905260409020555b5b61078d8061004a6000396000f300606060405236156100965763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610098578063095ea7b31461014657806318160ddd1461018657806323b872dd146101a8578063313ce567146101ee57806370a082311461021457806395d89b411461024f578063a9059cbb146102fd578063dd62ed3e1461033d575bfe5b34156100a057fe5b6100a861037e565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014e57fe5b61017273ffffffffffffffffffffffffffffffffffffffff600435166024356103b5565b604080519115158252519081900360200190f35b341561018e57fe5b61019661042d565b60408051918252519081900360200190f35b34156101b057fe5b61017273ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610433565b604080519115158252519081900360200190f35b34156101f657fe5b6101fe6105d4565b6040805160ff9092168252519081900360200190f35b341561021c57fe5b61019673ffffffffffffffffffffffffffffffffffffffff600435166105d9565b60408051918252519081900360200190f35b341561025757fe5b6100a8610605565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561030557fe5b61017273ffffffffffffffffffffffffffffffffffffffff6004351660243561063c565b604080519115158252519081900360200190f35b341561034557fe5b61019673ffffffffffffffffffffffffffffffffffffffff60043581169060243516610727565b60408051918252519081900360200190f35b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104835750828110155b80156104b6575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156105c65773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156105585773ffffffffffffffffffffffffffffffffffffffff808616600090815260016020908152604080832033909416835292905220805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506105cb565b600091505b5b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812054829010801590610699575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b156107185773ffffffffffffffffffffffffffffffffffffffff33811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3506001610427565b506000610427565b5b92915050565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600160209081526040808320938516835292905220545b929150505600a165627a7a7230582046535601227b5593da4370a7dfeedd2cba029ac1cbef52fe6cae0e64fbbb37ce0029"
"object": "0x60606040526b033b2e3c9fd0803ce8000000600355341561001c57fe5b5b600354600160a060020a0333166000908152602081905260409020555b5b61078d8061004a6000396000f300606060405236156100965763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610098578063095ea7b31461014657806318160ddd1461018657806323b872dd146101a8578063313ce567146101ee57806370a082311461021457806395d89b411461024f578063a9059cbb146102fd578063dd62ed3e1461033d575bfe5b34156100a057fe5b6100a861037e565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014e57fe5b61017273ffffffffffffffffffffffffffffffffffffffff600435166024356103b5565b604080519115158252519081900360200190f35b341561018e57fe5b61019661042d565b60408051918252519081900360200190f35b34156101b057fe5b61017273ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610433565b604080519115158252519081900360200190f35b34156101f657fe5b6101fe6105d4565b6040805160ff9092168252519081900360200190f35b341561021c57fe5b61019673ffffffffffffffffffffffffffffffffffffffff600435166105d9565b60408051918252519081900360200190f35b341561025757fe5b6100a8610605565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561030557fe5b61017273ffffffffffffffffffffffffffffffffffffffff6004351660243561063c565b604080519115158252519081900360200190f35b341561034557fe5b61019673ffffffffffffffffffffffffffffffffffffffff60043581169060243516610727565b60408051918252519081900360200190f35b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104835750828110155b80156104b6575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156105c65773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156105585773ffffffffffffffffffffffffffffffffffffffff808616600090815260016020908152604080832033909416835292905220805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506105cb565b600091505b5b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812054829010801590610699575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b156107185773ffffffffffffffffffffffffffffffffffffffff33811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3506001610427565b506000610427565b5b92915050565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600160209081526040808320938516835292905220545b929150505600a165627a7a723058207bda76ca54110f114be74ab23875a2d1613700e2cc4fdadfc8f235d9729b4c450029"
},
"deployedBytecode": {
"object": "0x606060405236156100965763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610098578063095ea7b31461014657806318160ddd1461018657806323b872dd146101a8578063313ce567146101ee57806370a082311461021457806395d89b411461024f578063a9059cbb146102fd578063dd62ed3e1461033d575bfe5b34156100a057fe5b6100a861037e565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014e57fe5b61017273ffffffffffffffffffffffffffffffffffffffff600435166024356103b5565b604080519115158252519081900360200190f35b341561018e57fe5b61019661042d565b60408051918252519081900360200190f35b34156101b057fe5b61017273ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610433565b604080519115158252519081900360200190f35b34156101f657fe5b6101fe6105d4565b6040805160ff9092168252519081900360200190f35b341561021c57fe5b61019673ffffffffffffffffffffffffffffffffffffffff600435166105d9565b60408051918252519081900360200190f35b341561025757fe5b6100a8610605565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561030557fe5b61017273ffffffffffffffffffffffffffffffffffffffff6004351660243561063c565b604080519115158252519081900360200190f35b341561034557fe5b61019673ffffffffffffffffffffffffffffffffffffffff60043581169060243516610727565b60408051918252519081900360200190f35b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104835750828110155b80156104b6575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156105c65773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156105585773ffffffffffffffffffffffffffffffffffffffff808616600090815260016020908152604080832033909416835292905220805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506105cb565b600091505b5b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812054829010801590610699575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b156107185773ffffffffffffffffffffffffffffffffffffffff33811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3506001610427565b506000610427565b5b92915050565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600160209081526040808320938516835292905220545b929150505600a165627a7a7230582046535601227b5593da4370a7dfeedd2cba029ac1cbef52fe6cae0e64fbbb37ce0029"
"object": "0x606060405236156100965763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610098578063095ea7b31461014657806318160ddd1461018657806323b872dd146101a8578063313ce567146101ee57806370a082311461021457806395d89b411461024f578063a9059cbb146102fd578063dd62ed3e1461033d575bfe5b34156100a057fe5b6100a861037e565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014e57fe5b61017273ffffffffffffffffffffffffffffffffffffffff600435166024356103b5565b604080519115158252519081900360200190f35b341561018e57fe5b61019661042d565b60408051918252519081900360200190f35b34156101b057fe5b61017273ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610433565b604080519115158252519081900360200190f35b34156101f657fe5b6101fe6105d4565b6040805160ff9092168252519081900360200190f35b341561021c57fe5b61019673ffffffffffffffffffffffffffffffffffffffff600435166105d9565b60408051918252519081900360200190f35b341561025757fe5b6100a8610605565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561030557fe5b61017273ffffffffffffffffffffffffffffffffffffffff6004351660243561063c565b604080519115158252519081900360200190f35b341561034557fe5b61019673ffffffffffffffffffffffffffffffffffffffff60043581169060243516610727565b60408051918252519081900360200190f35b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104835750828110155b80156104b6575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156105c65773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156105585773ffffffffffffffffffffffffffffffffffffffff808616600090815260016020908152604080832033909416835292905220805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506105cb565b600091505b5b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812054829010801590610699575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b156107185773ffffffffffffffffffffffffffffffffffffffff33811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3506001610427565b506000610427565b5b92915050565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600160209081526040808320938516835292905220545b929150505600a165627a7a723058207bda76ca54110f114be74ab23875a2d1613700e2cc4fdadfc8f235d9729b4c450029"
}
}
},

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contract-artifacts",
"version": "3.17.0",
"version": "3.18.0",
"engines": {
"node": ">=6.12"
},
@@ -30,13 +30,13 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/packages/contract-artifacts",
"devDependencies": {
"@0x/utils": "^6.5.0",
"@0x/utils": "^6.5.3",
"@types/mocha": "^5.2.7",
"chai": "^4.0.1",
"lodash": "^4.17.11",
"mocha": "^6.2.0",
"shx": "^0.2.2",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,32 @@
[
{
"timestamp": 1650611093,
"version": "13.20.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "13.20.0",
"changes": [
{
"note": "Regenerate all wrappers",
"pr": 449
}
],
"timestamp": 1648739346
},
{
"timestamp": 1646225739,
"version": "13.19.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "13.19.0",
"changes": [

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v13.20.1 - _April 22, 2022_
* Dependencies updated
## v13.20.0 - _March 31, 2022_
* Regenerate all wrappers (#449)
## v13.19.1 - _March 2, 2022_
* Dependencies updated
## v13.19.0 - _February 22, 2022_
* Regenerate wrappers to add ContractTxFunctionObj.selector (#429)

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contract-wrappers",
"version": "13.19.0",
"version": "13.20.1",
"engines": {
"node": ">=6.12"
},
@@ -52,17 +52,17 @@
"gitpkg": "https://github.com/0xProject/gitpkg.git",
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typescript": "4.2.2"
"typescript": "4.6.3"
},
"dependencies": {
"@0x/assert": "^3.0.31",
"@0x/base-contract": "^6.4.5",
"@0x/contract-addresses": "^6.11.0",
"@0x/json-schemas": "^6.4.1",
"@0x/types": "^3.3.4",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"ethereum-types": "^3.6.0",
"@0x/assert": "^3.0.34",
"@0x/base-contract": "^6.5.0",
"@0x/contract-addresses": "^6.13.0",
"@0x/json-schemas": "^6.4.4",
"@0x/types": "^3.3.6",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"ethereum-types": "^3.7.0",
"ethers": "~4.0.4"
},
"publishConfig": {

View File

@@ -475,7 +475,7 @@ export class BrokerContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -499,7 +499,7 @@ export class CoordinatorContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -1516,7 +1516,7 @@ export class DevUtilsContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -347,7 +347,7 @@ export class ERC20TokenContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -437,7 +437,7 @@ export class ERC721TokenContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -3147,7 +3147,7 @@ export class ExchangeContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -699,7 +699,7 @@ export class ForwarderContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -201,7 +201,7 @@ export class GodsUnchainedValidatorContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -270,7 +270,7 @@ export class IAssetDataContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -251,7 +251,7 @@ export class ILiquidityProviderContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -415,7 +415,7 @@ export class ITransformERC20Contract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -7149,7 +7149,7 @@ export class IZeroExContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -173,7 +173,7 @@ export class MaximumGasPriceContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -1616,7 +1616,7 @@ export class StakingContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -743,7 +743,7 @@ export class StakingProxyContract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -471,7 +471,7 @@ export class WETH9Contract extends BaseContract {
txDefaults: Partial<TxData>,
libraryAddresses: { [libraryName: string]: string } = {},
): Promise<{ [libraryName: string]: string }> {
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
const links = artifact.compilerOutput.evm.bytecode.linkReferences || {};
// Go through all linked libraries, recursively deploying them if necessary.
for (const link of Object.values(links)) {
for (const libraryName of Object.keys(link)) {

View File

@@ -1,4 +1,31 @@
[
{
"timestamp": 1650611093,
"version": "8.1.18",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1648739346,
"version": "8.1.17",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1646225739,
"version": "8.1.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1645569128,
"version": "8.1.15",

View File

@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v8.1.18 - _April 22, 2022_
* Dependencies updated
## v8.1.17 - _March 31, 2022_
* Dependencies updated
## v8.1.16 - _March 2, 2022_
* Dependencies updated
## v8.1.15 - _February 22, 2022_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/migrations",
"version": "8.1.15",
"version": "8.1.18",
"engines": {
"node": ">=6.12"
},
@@ -48,10 +48,10 @@
"registry": "git@github.com:0xProject/gitpkg-registry.git"
},
"devDependencies": {
"@0x/dev-utils": "^4.2.11",
"@0x/dev-utils": "^4.2.14",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.4",
"@0x/types": "^3.3.4",
"@0x/types": "^3.3.6",
"@types/yargs": "^11.0.0",
"chai": "^4.0.1",
"dirty-chai": "^2.0.1",
@@ -62,34 +62,34 @@
"shx": "^0.2.2",
"tslint": "5.11.0",
"typedoc": "~0.16.11",
"typescript": "4.2.2",
"typescript": "4.6.3",
"web3-provider-engine": "14.0.6",
"yargs": "^10.0.3"
},
"dependencies": {
"@0x/base-contract": "^6.4.5",
"@0x/contract-addresses": "^6.11.0",
"@0x/base-contract": "^6.5.0",
"@0x/contract-addresses": "^6.13.0",
"@0x/contracts-asset-proxy": "^3.7.19",
"@0x/contracts-coordinator": "^3.1.38",
"@0x/contracts-dev-utils": "^1.3.36",
"@0x/contracts-erc1155": "^2.1.37",
"@0x/contracts-erc20": "^3.3.26",
"@0x/contracts-erc20": "^3.3.29",
"@0x/contracts-erc721": "^3.1.37",
"@0x/contracts-exchange": "^3.2.38",
"@0x/contracts-exchange-forwarder": "^4.2.38",
"@0x/contracts-extensions": "^6.2.32",
"@0x/contracts-multisig": "^4.1.38",
"@0x/contracts-staking": "^2.0.45",
"@0x/contracts-utils": "^4.8.7",
"@0x/contracts-zero-ex": "^0.31.0",
"@0x/sol-compiler": "^4.7.8",
"@0x/subproviders": "^6.6.2",
"@0x/typescript-typings": "^5.2.1",
"@0x/utils": "^6.5.0",
"@0x/web3-wrapper": "^7.6.2",
"@0x/contracts-utils": "^4.8.10",
"@0x/contracts-zero-ex": "^0.32.0",
"@0x/sol-compiler": "^4.8.1",
"@0x/subproviders": "^6.6.5",
"@0x/typescript-typings": "^5.3.1",
"@0x/utils": "^6.5.3",
"@0x/web3-wrapper": "^7.6.5",
"@ledgerhq/hw-app-eth": "^4.3.0",
"@types/web3-provider-engine": "^14.0.0",
"ethereum-types": "^3.6.0",
"ethereum-types": "^3.7.0",
"ethereumjs-util": "^7.1.0",
"ethers": "~4.0.4",
"lodash": "^4.17.11"

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