Compare commits
12 Commits
protocol@d
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
d2018f07a2 | ||
|
d2e57d8163 | ||
|
7403c0255a | ||
|
75dcd687e2 | ||
|
afd4805421 | ||
|
6aa582d140 | ||
|
534d92fa00 | ||
|
37aae134ab | ||
|
36bd8f68c9 | ||
|
c3ad42221e | ||
|
602ac1f626 | ||
|
3126795efe |
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "3.6.5",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "3.6.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "3.6.3",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.6.5 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.6.4 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.6.3 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-asset-proxy",
|
||||
"version": "3.6.3",
|
||||
"version": "3.6.5",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,10 +52,10 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contract-wrappers": "^13.9.4",
|
||||
"@0x/contract-wrappers": "^13.10.0",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -80,11 +80,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-erc1155": "^2.1.12",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc721": "^3.1.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/contracts-erc1155": "^2.1.14",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-erc721": "^3.1.14",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/types": "^3.3.0",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^6.1.0",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "1.1.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "1.1.12",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "1.1.11",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.13 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.11 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-broker",
|
||||
"version": "1.1.11",
|
||||
"version": "1.1.13",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,14 +52,14 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc721": "^3.1.12",
|
||||
"@0x/contracts-exchange": "^3.2.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-erc721": "^3.1.14",
|
||||
"@0x/contracts-exchange": "^3.2.14",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -85,7 +85,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^6.1.0",
|
||||
"ethereum-types": "^3.3.3"
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "3.1.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "3.1.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "3.1.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-coordinator",
|
||||
"version": "3.1.12",
|
||||
"version": "3.1.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,12 +53,12 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.10",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-dev-utils": "^1.3.12",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -84,10 +84,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.17",
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contract-addresses": "^5.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.12",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contract-addresses": "^5.3.0",
|
||||
"@0x/contracts-exchange": "^3.2.14",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/json-schemas": "^5.3.3",
|
||||
"@0x/types": "^3.3.0",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "1.3.12",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "1.3.11",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "1.3.10",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.3.12 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.11 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.10 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-dev-utils",
|
||||
"version": "1.3.10",
|
||||
"version": "1.3.12",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -43,10 +43,10 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/assert": "^3.0.17",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "2.1.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "2.1.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "2.1.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc1155",
|
||||
"version": "2.1.12",
|
||||
"version": "2.1.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,7 +54,7 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -81,7 +81,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/utils": "^6.1.0",
|
||||
"@0x/web3-wrapper": "^7.2.8",
|
||||
"lodash": "^4.17.11"
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "3.2.8",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "3.2.7",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "3.2.6",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.8 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.7 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.6 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc20",
|
||||
"version": "3.2.6",
|
||||
"version": "3.2.8",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,8 +53,8 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "3.1.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "3.1.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "3.1.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc721",
|
||||
"version": "3.1.12",
|
||||
"version": "3.1.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,8 +54,8 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "4.2.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "4.2.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "4.2.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.2.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-forwarder",
|
||||
"version": "4.2.12",
|
||||
"version": "4.2.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,18 +53,18 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.10",
|
||||
"@0x/contracts-erc1155": "^2.1.12",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc721": "^3.1.12",
|
||||
"@0x/contracts-exchange": "^3.2.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-dev-utils": "^1.3.12",
|
||||
"@0x/contracts-erc1155": "^2.1.14",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-erc721": "^3.1.14",
|
||||
"@0x/contracts-exchange": "^3.2.14",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "4.3.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "4.3.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "4.3.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.3.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-libs",
|
||||
"version": "4.3.12",
|
||||
"version": "4.3.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -81,9 +81,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/types": "^3.3.0",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^6.1.0",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "3.2.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "3.2.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "3.2.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange",
|
||||
"version": "3.2.12",
|
||||
"version": "3.2.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,13 +53,13 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-multisig": "^4.1.12",
|
||||
"@0x/contracts-staking": "^2.0.19",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-multisig": "^4.1.14",
|
||||
"@0x/contracts-staking": "^2.0.21",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -89,11 +89,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-dev-utils": "^1.3.10",
|
||||
"@0x/contracts-erc1155": "^2.1.12",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc721": "^3.1.12",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/contracts-dev-utils": "^1.3.12",
|
||||
"@0x/contracts-erc1155": "^2.1.14",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-erc721": "^3.1.14",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/utils": "^6.1.0",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "6.2.8",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "6.2.7",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "6.2.6",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v6.2.8 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.7 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.6 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "6.2.6",
|
||||
"version": "6.2.8",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,16 +53,16 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.10",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc721": "^3.1.12",
|
||||
"@0x/contracts-exchange": "^3.2.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-dev-utils": "^1.3.12",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-erc721": "^3.1.14",
|
||||
"@0x/contracts-exchange": "^3.2.14",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"ethereum-types": "^3.3.3"
|
||||
},
|
||||
|
@@ -1,4 +1,31 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "2.7.8",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604620645,
|
||||
"version": "2.7.7",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "2.7.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "2.7.5",
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.7.8 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.7.7 - _November 5, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.7.6 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.7.5 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-integrations",
|
||||
"version": "2.7.5",
|
||||
"version": "2.7.8",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,20 +52,20 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contract-addresses": "^5.1.0",
|
||||
"@0x/contract-wrappers": "^13.9.4",
|
||||
"@0x/contracts-broker": "^1.1.11",
|
||||
"@0x/contracts-coordinator": "^3.1.12",
|
||||
"@0x/contracts-dev-utils": "^1.3.10",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-extensions": "^6.2.6",
|
||||
"@0x/contract-addresses": "^5.3.0",
|
||||
"@0x/contract-wrappers": "^13.10.0",
|
||||
"@0x/contracts-broker": "^1.1.13",
|
||||
"@0x/contracts-coordinator": "^3.1.14",
|
||||
"@0x/contracts-dev-utils": "^1.3.12",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.14",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-extensions": "^6.2.8",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/coordinator-server": "^1.0.5",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/migrations": "^6.4.6",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/migrations": "^6.5.0",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
"@0x/web3-wrapper": "^7.2.8",
|
||||
@@ -91,17 +91,17 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/asset-swapper": "^5.0.1",
|
||||
"@0x/asset-swapper": "^5.1.0",
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-erc1155": "^2.1.12",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc721": "^3.1.12",
|
||||
"@0x/contracts-exchange": "^3.2.12",
|
||||
"@0x/contracts-multisig": "^4.1.12",
|
||||
"@0x/contracts-staking": "^2.0.19",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-zero-ex": "^0.7.0",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-erc1155": "^2.1.14",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-erc721": "^3.1.14",
|
||||
"@0x/contracts-exchange": "^3.2.14",
|
||||
"@0x/contracts-multisig": "^4.1.14",
|
||||
"@0x/contracts-staking": "^2.0.21",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-zero-ex": "^0.9.0",
|
||||
"@0x/subproviders": "^6.1.9",
|
||||
"@0x/types": "^3.3.0",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "4.1.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "4.1.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "4.1.12",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.1.14 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.13 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.12 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-multisig",
|
||||
"version": "4.1.12",
|
||||
"version": "4.1.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -50,11 +50,11 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "2.0.21",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "2.0.20",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "2.0.19",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.0.21 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.20 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.19 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-staking",
|
||||
"version": "2.0.19",
|
||||
"version": "2.0.21",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,14 +54,14 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-dev-utils": "^1.3.10",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-dev-utils": "^1.3.12",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -88,7 +88,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^6.1.0",
|
||||
"ethereum-types": "^3.3.3",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "5.3.11",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "5.3.10",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "5.3.9",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v5.3.11 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.3.10 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.3.9 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-test-utils",
|
||||
"version": "5.3.9",
|
||||
"version": "5.3.11",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -44,10 +44,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.17",
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contract-addresses": "^5.1.0",
|
||||
"@0x/contract-addresses": "^5.3.0",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/json-schemas": "^5.3.3",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-coverage": "^4.0.18",
|
||||
"@0x/sol-profiler": "^4.1.8",
|
||||
"@0x/sol-trace": "^3.0.18",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1605302002,
|
||||
"version": "4.5.8",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "4.5.7",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "4.5.6",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.5.8 - _November 13, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.5.7 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.5.6 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-utils",
|
||||
"version": "4.5.6",
|
||||
"version": "4.5.8",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,9 +52,9 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
"@0x/types": "^3.3.0",
|
||||
|
@@ -1,4 +1,36 @@
|
||||
[
|
||||
{
|
||||
"version": "0.9.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Rewrite the ZeroEx contract in Yul",
|
||||
"pr": 23
|
||||
},
|
||||
{
|
||||
"note": "Update LiquidityProviderFeature to use off-chain registry and sandbox",
|
||||
"pr": 16
|
||||
},
|
||||
{
|
||||
"note": "Update ILiquidityProvider interface",
|
||||
"pr": 16
|
||||
},
|
||||
{
|
||||
"note": "Update ProtocolFeeUnfunded event to emit order hash",
|
||||
"pr": 16
|
||||
}
|
||||
],
|
||||
"timestamp": 1605302002
|
||||
},
|
||||
{
|
||||
"version": "0.8.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Trust LP boughtAmount return value",
|
||||
"pr": 29
|
||||
}
|
||||
],
|
||||
"timestamp": 1604385937
|
||||
},
|
||||
{
|
||||
"version": "0.7.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,17 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.9.0 - _November 13, 2020_
|
||||
|
||||
* Rewrite the ZeroEx contract in Yul (#23)
|
||||
* Update LiquidityProviderFeature to use off-chain registry and sandbox (#16)
|
||||
* Update ILiquidityProvider interface (#16)
|
||||
* Update ProtocolFeeUnfunded event to emit order hash (#16)
|
||||
|
||||
## v0.8.0 - _November 3, 2020_
|
||||
|
||||
* Trust LP boughtAmount return value (#29)
|
||||
|
||||
## v0.7.0 - _November 3, 2020_
|
||||
|
||||
* Change `ProtocolFeeUnfunded` event in FQT (#28)
|
||||
|
@@ -44,14 +44,4 @@ interface IZeroEx is
|
||||
|
||||
/// @dev Fallback for just receiving ether.
|
||||
receive() external payable;
|
||||
|
||||
// solhint-enable state-visibility
|
||||
|
||||
/// @dev Get the implementation contract of a registered function.
|
||||
/// @param selector The function selector.
|
||||
/// @return impl The implementation contract address.
|
||||
function getFunctionImplementation(bytes4 selector)
|
||||
external
|
||||
view
|
||||
returns (address impl);
|
||||
}
|
||||
|
@@ -19,19 +19,12 @@
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
import "./migrations/LibBootstrap.sol";
|
||||
import "./features/BootstrapFeature.sol";
|
||||
import "./storage/LibProxyStorage.sol";
|
||||
import "./errors/LibProxyRichErrors.sol";
|
||||
|
||||
|
||||
/// @dev An extensible proxy contract that serves as a universal entry point for
|
||||
/// interacting with the 0x protocol.
|
||||
contract ZeroEx {
|
||||
// solhint-disable separate-by-one-line-in-contract,indent,var-name-mixedcase
|
||||
using LibBytesV06 for bytes;
|
||||
|
||||
/// @dev Construct this contract and register the `BootstrapFeature` feature.
|
||||
/// After constructing this contract, `bootstrap()` should be called
|
||||
/// by `bootstrap()` to seed the initial feature set.
|
||||
@@ -44,48 +37,55 @@ contract ZeroEx {
|
||||
address(bootstrap);
|
||||
}
|
||||
|
||||
|
||||
// solhint-disable state-visibility
|
||||
|
||||
/// @dev Forwards calls to the appropriate implementation contract.
|
||||
fallback() external payable {
|
||||
bytes4 selector = msg.data.readBytes4(0);
|
||||
address impl = getFunctionImplementation(selector);
|
||||
if (impl == address(0)) {
|
||||
_revertWithData(LibProxyRichErrors.NotImplementedError(selector));
|
||||
// This is used in assembly below as impls_slot.
|
||||
mapping(bytes4 => address) storage impls =
|
||||
LibProxyStorage.getStorage().impls;
|
||||
|
||||
assembly {
|
||||
let cdlen := calldatasize()
|
||||
|
||||
// equivalent of receive() external payable {}
|
||||
if iszero(cdlen) {
|
||||
return(0, 0)
|
||||
}
|
||||
|
||||
// Store at 0x40, to leave 0x00-0x3F for slot calculation below.
|
||||
calldatacopy(0x40, 0, cdlen)
|
||||
let selector := and(mload(0x40), 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
|
||||
|
||||
// Slot for impls[selector] is keccak256(selector . impls_slot).
|
||||
mstore(0, selector)
|
||||
mstore(0x20, impls_slot)
|
||||
let slot := keccak256(0, 0x40)
|
||||
|
||||
let delegate := sload(slot)
|
||||
if iszero(delegate) {
|
||||
// Revert with:
|
||||
// abi.encodeWithSelector(
|
||||
// bytes4(keccak256("NotImplementedError(bytes4)")),
|
||||
// selector)
|
||||
mstore(0, 0x734e6e1c00000000000000000000000000000000000000000000000000000000)
|
||||
mstore(4, selector)
|
||||
revert(0, 0x24)
|
||||
}
|
||||
|
||||
let success := delegatecall(
|
||||
gas(),
|
||||
delegate,
|
||||
0x40, cdlen,
|
||||
0, 0
|
||||
)
|
||||
let rdlen := returndatasize()
|
||||
returndatacopy(0, 0, rdlen)
|
||||
if success {
|
||||
return(0, rdlen)
|
||||
}
|
||||
revert(0, rdlen)
|
||||
}
|
||||
|
||||
(bool success, bytes memory resultData) = impl.delegatecall(msg.data);
|
||||
if (!success) {
|
||||
_revertWithData(resultData);
|
||||
}
|
||||
_returnWithData(resultData);
|
||||
}
|
||||
|
||||
/// @dev Fallback for just receiving ether.
|
||||
receive() external payable {}
|
||||
|
||||
// solhint-enable state-visibility
|
||||
|
||||
/// @dev Get the implementation contract of a registered function.
|
||||
/// @param selector The function selector.
|
||||
/// @return impl The implementation contract address.
|
||||
function getFunctionImplementation(bytes4 selector)
|
||||
public
|
||||
view
|
||||
returns (address impl)
|
||||
{
|
||||
return LibProxyStorage.getStorage().impls[selector];
|
||||
}
|
||||
|
||||
/// @dev Revert with arbitrary bytes.
|
||||
/// @param data Revert data.
|
||||
function _revertWithData(bytes memory data) private pure {
|
||||
assembly { revert(add(data, 32), mload(data)) }
|
||||
}
|
||||
|
||||
/// @dev Return with arbitrary bytes.
|
||||
/// @param data Return data.
|
||||
function _returnWithData(bytes memory data) private pure {
|
||||
assembly { return(add(data, 32), mload(data)) }
|
||||
}
|
||||
}
|
||||
|
@@ -45,19 +45,4 @@ library LibLiquidityProviderRichErrors {
|
||||
minBuyAmount
|
||||
);
|
||||
}
|
||||
|
||||
function NoLiquidityProviderForMarketError(
|
||||
address xAsset,
|
||||
address yAsset
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
bytes4(keccak256("NoLiquidityProviderForMarketError(address,address)")),
|
||||
xAsset,
|
||||
yAsset
|
||||
);
|
||||
}
|
||||
}
|
||||
|
74
contracts/zero-ex/contracts/src/external/ILiquidityProviderSandbox.sol
vendored
Normal file
74
contracts/zero-ex/contracts/src/external/ILiquidityProviderSandbox.sol
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
|
||||
|
||||
interface ILiquidityProviderSandbox {
|
||||
|
||||
/// @dev Calls `sellTokenForToken` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellTokenForToken(
|
||||
address provider,
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Calls `sellEthForToken` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellEthForToken(
|
||||
address provider,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Calls `sellTokenForEth` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of ETH to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellTokenForEth(
|
||||
address provider,
|
||||
address inputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external;
|
||||
}
|
139
contracts/zero-ex/contracts/src/external/LiquidityProviderSandbox.sol
vendored
Normal file
139
contracts/zero-ex/contracts/src/external/LiquidityProviderSandbox.sol
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
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-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibOwnableRichErrorsV06.sol";
|
||||
import "../vendor/ILiquidityProvider.sol";
|
||||
import "../vendor/v3/IERC20Bridge.sol";
|
||||
import "./ILiquidityProviderSandbox.sol";
|
||||
|
||||
|
||||
/// @dev A permissionless contract through which the ZeroEx contract can
|
||||
/// safely trigger a trade on an external `ILiquidityProvider` contract.
|
||||
contract LiquidityProviderSandbox is
|
||||
ILiquidityProviderSandbox
|
||||
{
|
||||
using LibRichErrorsV06 for bytes;
|
||||
|
||||
/// @dev Store the owner as an immutable.
|
||||
address public immutable owner;
|
||||
|
||||
constructor(address owner_)
|
||||
public
|
||||
{
|
||||
owner = owner_;
|
||||
}
|
||||
|
||||
/// @dev Allows only the (immutable) owner to call a function.
|
||||
modifier onlyOwner() virtual {
|
||||
if (msg.sender != owner) {
|
||||
LibOwnableRichErrorsV06.OnlyOwnerError(
|
||||
msg.sender,
|
||||
owner
|
||||
).rrevert();
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
/// @dev Calls `sellTokenForToken` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellTokenForToken(
|
||||
address provider,
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
override
|
||||
{
|
||||
try ILiquidityProvider(provider).sellTokenForToken(
|
||||
inputToken,
|
||||
outputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
auxiliaryData
|
||||
) {} catch {
|
||||
IERC20Bridge(provider).bridgeTransferFrom(
|
||||
outputToken,
|
||||
provider,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
auxiliaryData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Calls `sellEthForToken` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellEthForToken(
|
||||
address provider,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
override
|
||||
{
|
||||
ILiquidityProvider(provider).sellEthForToken(
|
||||
outputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
auxiliaryData
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Calls `sellTokenForEth` on the given `provider` contract to
|
||||
/// trigger a trade.
|
||||
/// @param provider The address of the on-chain liquidity provider.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of ETH to buy.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
function executeSellTokenForEth(
|
||||
address provider,
|
||||
address inputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
override
|
||||
{
|
||||
ILiquidityProvider(provider).sellTokenForEth(
|
||||
inputToken,
|
||||
payable(recipient),
|
||||
minBuyAmount,
|
||||
auxiliaryData
|
||||
);
|
||||
}
|
||||
}
|
@@ -22,45 +22,30 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
/// @dev Feature to swap directly with an on-chain liquidity provider.
|
||||
interface ILiquidityProviderFeature {
|
||||
event LiquidityProviderForMarketUpdated(
|
||||
address indexed xAsset,
|
||||
address indexed yAsset,
|
||||
address providerAddress
|
||||
);
|
||||
|
||||
/// @dev Sells `sellAmount` of `inputToken` to the liquidity provider
|
||||
/// at the given `provider` address.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param provider The address of the on-chain liquidity provider
|
||||
/// to trade with.
|
||||
/// @param recipient The recipient of the bought tokens. If equal to
|
||||
/// address(0), `msg.sender` is assumed to be the recipient.
|
||||
/// @param sellAmount The amount of `inputToken` to sell.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to
|
||||
/// buy. Reverts if this amount is not satisfied.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
/// @return boughtAmount The amount of `outputToken` bought.
|
||||
function sellToLiquidityProvider(
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
address payable recipient,
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address payable provider,
|
||||
address recipient,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 boughtAmount);
|
||||
|
||||
/// @dev Sets address of the liquidity provider for a market given
|
||||
/// (xAsset, yAsset).
|
||||
/// @param xAsset First asset managed by the liquidity provider.
|
||||
/// @param yAsset Second asset managed by the liquidity provider.
|
||||
/// @param providerAddress Address of the liquidity provider.
|
||||
function setLiquidityProviderForMarket(
|
||||
address xAsset,
|
||||
address yAsset,
|
||||
address providerAddress
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Returns the address of the liquidity provider for a market given
|
||||
/// (xAsset, yAsset), or reverts if pool does not exist.
|
||||
/// @param xAsset First asset managed by the liquidity provider.
|
||||
/// @param yAsset Second asset managed by the liquidity provider.
|
||||
/// @return providerAddress Address of the liquidity provider.
|
||||
function getLiquidityProviderForMarket(
|
||||
address xAsset,
|
||||
address yAsset
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address providerAddress);
|
||||
}
|
||||
|
@@ -57,4 +57,12 @@ interface ISimpleFunctionRegistryFeature {
|
||||
external
|
||||
view
|
||||
returns (address impl);
|
||||
|
||||
/// @dev Get the implementation contract of a registered function.
|
||||
/// @param selector The function selector.
|
||||
/// @return impl The implementation contract address.
|
||||
function getFunctionImplementation(bytes4 selector)
|
||||
external
|
||||
view
|
||||
returns (address impl);
|
||||
}
|
||||
|
@@ -20,15 +20,13 @@ pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
import "../errors/LibLiquidityProviderRichErrors.sol";
|
||||
import "../external/ILiquidityProviderSandbox.sol";
|
||||
import "../external/LiquidityProviderSandbox.sol";
|
||||
import "../fixins/FixinCommon.sol";
|
||||
import "../migrations/LibMigrate.sol";
|
||||
import "../storage/LibLiquidityProviderStorage.sol";
|
||||
import "../vendor/v3/IERC20Bridge.sol";
|
||||
import "./IFeature.sol";
|
||||
import "./ILiquidityProviderFeature.sol";
|
||||
import "./libs/LibTokenSpender.sol";
|
||||
@@ -39,7 +37,6 @@ contract LiquidityProviderFeature is
|
||||
ILiquidityProviderFeature,
|
||||
FixinCommon
|
||||
{
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
using LibSafeMathV06 for uint256;
|
||||
using LibRichErrorsV06 for bytes;
|
||||
|
||||
@@ -50,16 +47,24 @@ contract LiquidityProviderFeature is
|
||||
|
||||
/// @dev ETH pseudo-token address.
|
||||
address constant internal ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
/// @dev The WETH contract address.
|
||||
IEtherTokenV06 public immutable weth;
|
||||
/// @dev The sandbox contract address.
|
||||
ILiquidityProviderSandbox public immutable sandbox;
|
||||
|
||||
/// @dev Store the WETH address in an immutable.
|
||||
/// @param weth_ The weth token.
|
||||
constructor(IEtherTokenV06 weth_)
|
||||
/// @dev Event for data pipeline.
|
||||
event LiquidityProviderSwap(
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
uint256 inputTokenAmount,
|
||||
uint256 outputTokenAmount,
|
||||
address provider,
|
||||
address recipient
|
||||
);
|
||||
|
||||
constructor(address zeroEx)
|
||||
public
|
||||
FixinCommon()
|
||||
{
|
||||
weth = weth_;
|
||||
sandbox = new LiquidityProviderSandbox(zeroEx);
|
||||
}
|
||||
|
||||
/// @dev Initialize and register this feature.
|
||||
@@ -70,131 +75,102 @@ contract LiquidityProviderFeature is
|
||||
returns (bytes4 success)
|
||||
{
|
||||
_registerFeatureFunction(this.sellToLiquidityProvider.selector);
|
||||
_registerFeatureFunction(this.setLiquidityProviderForMarket.selector);
|
||||
_registerFeatureFunction(this.getLiquidityProviderForMarket.selector);
|
||||
return LibMigrate.MIGRATE_SUCCESS;
|
||||
}
|
||||
|
||||
/// @dev Sells `sellAmount` of `inputToken` to the liquidity provider
|
||||
/// at the given `provider` address.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param provider The address of the on-chain liquidity provider
|
||||
/// to trade with.
|
||||
/// @param recipient The recipient of the bought tokens. If equal to
|
||||
/// address(0), `msg.sender` is assumed to be the recipient.
|
||||
/// @param sellAmount The amount of `inputToken` to sell.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to
|
||||
/// buy. Reverts if this amount is not satisfied.
|
||||
/// @param auxiliaryData Auxiliary data supplied to the `provider` contract.
|
||||
/// @return boughtAmount The amount of `outputToken` bought.
|
||||
function sellToLiquidityProvider(
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
address payable recipient,
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address payable provider,
|
||||
address recipient,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
override
|
||||
payable
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
address providerAddress = getLiquidityProviderForMarket(makerToken, takerToken);
|
||||
if (recipient == address(0)) {
|
||||
recipient = msg.sender;
|
||||
}
|
||||
|
||||
if (takerToken == ETH_TOKEN_ADDRESS) {
|
||||
// Wrap ETH.
|
||||
weth.deposit{value: sellAmount}();
|
||||
weth.transfer(providerAddress, sellAmount);
|
||||
if (inputToken == ETH_TOKEN_ADDRESS) {
|
||||
provider.transfer(sellAmount);
|
||||
} else {
|
||||
LibTokenSpender.spendERC20Tokens(
|
||||
IERC20TokenV06(takerToken),
|
||||
IERC20TokenV06(inputToken),
|
||||
msg.sender,
|
||||
providerAddress,
|
||||
provider,
|
||||
sellAmount
|
||||
);
|
||||
}
|
||||
|
||||
if (makerToken == ETH_TOKEN_ADDRESS) {
|
||||
uint256 balanceBefore = weth.balanceOf(address(this));
|
||||
IERC20Bridge(providerAddress).bridgeTransferFrom(
|
||||
address(weth),
|
||||
address(0),
|
||||
address(this),
|
||||
minBuyAmount,
|
||||
""
|
||||
);
|
||||
boughtAmount = weth.balanceOf(address(this)).safeSub(balanceBefore);
|
||||
// Unwrap wETH and send ETH to recipient.
|
||||
weth.withdraw(boughtAmount);
|
||||
recipient.transfer(boughtAmount);
|
||||
} else {
|
||||
uint256 balanceBefore = IERC20TokenV06(makerToken).balanceOf(recipient);
|
||||
IERC20Bridge(providerAddress).bridgeTransferFrom(
|
||||
makerToken,
|
||||
address(0),
|
||||
if (inputToken == ETH_TOKEN_ADDRESS) {
|
||||
uint256 balanceBefore = IERC20TokenV06(outputToken).balanceOf(recipient);
|
||||
sandbox.executeSellEthForToken(
|
||||
provider,
|
||||
outputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
""
|
||||
auxiliaryData
|
||||
);
|
||||
boughtAmount = IERC20TokenV06(makerToken).balanceOf(recipient).safeSub(balanceBefore);
|
||||
boughtAmount = IERC20TokenV06(outputToken).balanceOf(recipient).safeSub(balanceBefore);
|
||||
} else if (outputToken == ETH_TOKEN_ADDRESS) {
|
||||
uint256 balanceBefore = recipient.balance;
|
||||
sandbox.executeSellTokenForEth(
|
||||
provider,
|
||||
inputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
auxiliaryData
|
||||
);
|
||||
boughtAmount = recipient.balance.safeSub(balanceBefore);
|
||||
} else {
|
||||
uint256 balanceBefore = IERC20TokenV06(outputToken).balanceOf(recipient);
|
||||
sandbox.executeSellTokenForToken(
|
||||
provider,
|
||||
inputToken,
|
||||
outputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
auxiliaryData
|
||||
);
|
||||
boughtAmount = IERC20TokenV06(outputToken).balanceOf(recipient).safeSub(balanceBefore);
|
||||
}
|
||||
|
||||
if (boughtAmount < minBuyAmount) {
|
||||
LibLiquidityProviderRichErrors.LiquidityProviderIncompleteSellError(
|
||||
providerAddress,
|
||||
makerToken,
|
||||
takerToken,
|
||||
provider,
|
||||
outputToken,
|
||||
inputToken,
|
||||
sellAmount,
|
||||
boughtAmount,
|
||||
minBuyAmount
|
||||
).rrevert();
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sets address of the liquidity provider for a market given
|
||||
/// (xAsset, yAsset).
|
||||
/// @param xAsset First asset managed by the liquidity provider.
|
||||
/// @param yAsset Second asset managed by the liquidity provider.
|
||||
/// @param providerAddress Address of the liquidity provider.
|
||||
function setLiquidityProviderForMarket(
|
||||
address xAsset,
|
||||
address yAsset,
|
||||
address providerAddress
|
||||
)
|
||||
external
|
||||
override
|
||||
onlyOwner
|
||||
{
|
||||
LibLiquidityProviderStorage.getStorage()
|
||||
.addressBook[xAsset][yAsset] = providerAddress;
|
||||
LibLiquidityProviderStorage.getStorage()
|
||||
.addressBook[yAsset][xAsset] = providerAddress;
|
||||
emit LiquidityProviderForMarketUpdated(
|
||||
xAsset,
|
||||
yAsset,
|
||||
providerAddress
|
||||
emit LiquidityProviderSwap(
|
||||
inputToken,
|
||||
outputToken,
|
||||
sellAmount,
|
||||
boughtAmount,
|
||||
provider,
|
||||
recipient
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Returns the address of the liquidity provider for a market given
|
||||
/// (xAsset, yAsset), or reverts if pool does not exist.
|
||||
/// @param xAsset First asset managed by the liquidity provider.
|
||||
/// @param yAsset Second asset managed by the liquidity provider.
|
||||
/// @return providerAddress Address of the liquidity provider.
|
||||
function getLiquidityProviderForMarket(
|
||||
address xAsset,
|
||||
address yAsset
|
||||
)
|
||||
public
|
||||
view
|
||||
override
|
||||
returns (address providerAddress)
|
||||
{
|
||||
if (xAsset == ETH_TOKEN_ADDRESS) {
|
||||
providerAddress = LibLiquidityProviderStorage.getStorage()
|
||||
.addressBook[address(weth)][yAsset];
|
||||
} else if (yAsset == ETH_TOKEN_ADDRESS) {
|
||||
providerAddress = LibLiquidityProviderStorage.getStorage()
|
||||
.addressBook[xAsset][address(weth)];
|
||||
} else {
|
||||
providerAddress = LibLiquidityProviderStorage.getStorage()
|
||||
.addressBook[xAsset][yAsset];
|
||||
}
|
||||
if (providerAddress == address(0)) {
|
||||
LibLiquidityProviderRichErrors.NoLiquidityProviderForMarketError(
|
||||
xAsset,
|
||||
yAsset
|
||||
).rrevert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -56,6 +56,7 @@ contract SimpleFunctionRegistryFeature is
|
||||
// Register getters.
|
||||
_extend(this.getRollbackLength.selector, _implementation);
|
||||
_extend(this.getRollbackEntryAtIndex.selector, _implementation);
|
||||
_extend(this.getFunctionImplementation.selector, _implementation);
|
||||
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -151,6 +152,18 @@ contract SimpleFunctionRegistryFeature is
|
||||
return LibSimpleFunctionRegistryStorage.getStorage().implHistory[selector][idx];
|
||||
}
|
||||
|
||||
/// @dev Get the implementation contract of a registered function.
|
||||
/// @param selector The function selector.
|
||||
/// @return impl The implementation contract address.
|
||||
function getFunctionImplementation(bytes4 selector)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (address impl)
|
||||
{
|
||||
return LibProxyStorage.getStorage().impls[selector];
|
||||
}
|
||||
|
||||
/// @dev Register or replace a function.
|
||||
/// @param selector The function selector.
|
||||
/// @param impl The implementation contract for the function.
|
||||
|
@@ -58,7 +58,7 @@ contract TransformERC20Feature is
|
||||
/// @dev Name of this feature.
|
||||
string public constant override FEATURE_NAME = "TransformERC20";
|
||||
/// @dev Version of this feature.
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 2, 0);
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 0);
|
||||
|
||||
/// @dev Initialize and register this feature.
|
||||
/// Should be delegatecalled by `Migrate.migrate()`.
|
||||
|
@@ -37,7 +37,7 @@ contract UniswapFeature is
|
||||
/// @dev Name of this feature.
|
||||
string public constant override FEATURE_NAME = "UniswapFeature";
|
||||
/// @dev Version of this feature.
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
|
||||
/// @dev WETH contract.
|
||||
IEtherTokenV06 private immutable WETH;
|
||||
/// @dev AllowanceTarget instance.
|
||||
|
@@ -1,45 +0,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 "./LibStorage.sol";
|
||||
|
||||
|
||||
/// @dev Storage helpers for `LiquidityProviderFeature`.
|
||||
library LibLiquidityProviderStorage {
|
||||
|
||||
/// @dev Storage bucket for this feature.
|
||||
struct Storage {
|
||||
// Mapping of taker token -> maker token -> liquidity provider address
|
||||
// Note that addressBook[x][y] == addressBook[y][x] will always hold.
|
||||
mapping (address => mapping (address => address)) addressBook;
|
||||
}
|
||||
|
||||
/// @dev Get the storage bucket for this contract.
|
||||
function getStorage() internal pure returns (Storage storage stor) {
|
||||
uint256 storageSlot = LibStorage.getStorageSlot(
|
||||
LibStorage.StorageId.LiquidityProvider
|
||||
);
|
||||
// Dip into assembly to change the slot pointed to by the local
|
||||
// variable `stor`.
|
||||
// See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries
|
||||
assembly { stor_slot := storageSlot }
|
||||
}
|
||||
}
|
@@ -36,8 +36,7 @@ library LibStorage {
|
||||
TokenSpender,
|
||||
TransformERC20,
|
||||
MetaTransactions,
|
||||
ReentrancyGuard,
|
||||
LiquidityProvider
|
||||
ReentrancyGuard
|
||||
}
|
||||
|
||||
/// @dev Get the storage slot given a storage ID. We assign unique, well-spaced
|
||||
|
@@ -56,7 +56,6 @@ contract MixinZeroExBridge {
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
uint256 balanceBefore = buyToken.balanceOf(address(this));
|
||||
// Trade the good old fashioned way
|
||||
sellToken.compatTransfer(
|
||||
bridgeAddress,
|
||||
@@ -68,8 +67,8 @@ contract MixinZeroExBridge {
|
||||
address(this), // recipient
|
||||
1, // minBuyAmount
|
||||
bridgeData
|
||||
) {
|
||||
boughtAmount = buyToken.balanceOf(address(this)).safeSub(balanceBefore);
|
||||
) returns (uint256 _boughtAmount) {
|
||||
boughtAmount = _boughtAmount;
|
||||
emit ERC20BridgeTransfer(
|
||||
sellToken,
|
||||
buyToken,
|
||||
@@ -79,6 +78,7 @@ contract MixinZeroExBridge {
|
||||
address(this)
|
||||
);
|
||||
} catch {
|
||||
uint256 balanceBefore = buyToken.balanceOf(address(this));
|
||||
IERC20Bridge(bridgeAddress).bridgeTransferFrom(
|
||||
address(buyToken),
|
||||
bridgeAddress,
|
||||
|
@@ -1,19 +1,15 @@
|
||||
|
||||
/*
|
||||
|
||||
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;
|
||||
|
@@ -32,28 +32,26 @@ contract TestFillQuoteTransformerBridge {
|
||||
uint256 amount;
|
||||
}
|
||||
|
||||
bytes4 private constant ERC20_BRIDGE_PROXY_ID = 0xdc1600f3;
|
||||
|
||||
function bridgeTransferFrom(
|
||||
address tokenAddress,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata bridgeData
|
||||
function sellTokenForToken(
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
returns (bytes4 success)
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
FillBehavior memory behavior = abi.decode(bridgeData, (FillBehavior));
|
||||
TestMintableERC20Token(tokenAddress).mint(
|
||||
to,
|
||||
LibMathV06.getPartialAmountFloor(
|
||||
behavior.makerAssetMintRatio,
|
||||
1e18,
|
||||
behavior.amount
|
||||
)
|
||||
FillBehavior memory behavior = abi.decode(auxiliaryData, (FillBehavior));
|
||||
boughtAmount = LibMathV06.getPartialAmountFloor(
|
||||
behavior.makerAssetMintRatio,
|
||||
1e18,
|
||||
behavior.amount
|
||||
);
|
||||
TestMintableERC20Token(makerToken).mint(
|
||||
recipient,
|
||||
boughtAmount
|
||||
);
|
||||
return ERC20_BRIDGE_PROXY_ID;
|
||||
}
|
||||
|
||||
function encodeBehaviorData(FillBehavior calldata behavior)
|
||||
|
@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
|
||||
import "../src/ZeroEx.sol";
|
||||
import "../src/features/IBootstrapFeature.sol";
|
||||
import "../src/migrations/InitialMigration.sol";
|
||||
import "../src/features/SimpleFunctionRegistryFeature.sol";
|
||||
|
||||
|
||||
contract TestInitialMigration is
|
||||
@@ -44,7 +45,8 @@ contract TestInitialMigration is
|
||||
{
|
||||
success = InitialMigration.bootstrap(owner, features);
|
||||
// Snoop the bootstrap feature contract.
|
||||
bootstrapFeature = ZeroEx(address(uint160(address(this))))
|
||||
bootstrapFeature =
|
||||
SimpleFunctionRegistryFeature(address(uint160(address(this))))
|
||||
.getFunctionImplementation(IBootstrapFeature.bootstrap.selector);
|
||||
}
|
||||
|
||||
|
135
contracts/zero-ex/contracts/test/TestLiquidityProvider.sol
Normal file
135
contracts/zero-ex/contracts/test/TestLiquidityProvider.sol
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
|
||||
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/IERC20TokenV06.sol";
|
||||
|
||||
|
||||
contract TestLiquidityProvider {
|
||||
event SellTokenForToken(
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
uint256 inputTokenBalance
|
||||
);
|
||||
|
||||
event SellEthForToken(
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
uint256 ethBalance
|
||||
);
|
||||
|
||||
event SellTokenForEth(
|
||||
address inputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
uint256 inputTokenBalance
|
||||
);
|
||||
|
||||
IERC20TokenV06 public immutable xAsset;
|
||||
IERC20TokenV06 public immutable yAsset;
|
||||
|
||||
constructor(IERC20TokenV06 xAsset_, IERC20TokenV06 yAsset_)
|
||||
public
|
||||
{
|
||||
xAsset = xAsset_;
|
||||
yAsset = yAsset_;
|
||||
}
|
||||
|
||||
receive() external payable {}
|
||||
|
||||
/// @dev Trades `inputToken` for `outputToken`. The amount of `inputToken`
|
||||
/// to sell must be transferred to the contract prior to calling this
|
||||
/// function to trigger the trade.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Arbitrary auxiliary data supplied to the contract.
|
||||
/// @return boughtAmount The amount of `outputToken` bought.
|
||||
function sellTokenForToken(
|
||||
address inputToken,
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
emit SellTokenForToken(
|
||||
inputToken,
|
||||
outputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
IERC20TokenV06(inputToken).balanceOf(address(this))
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Trades ETH for token. ETH must be sent to the contract prior to
|
||||
/// calling this function to trigger the trade.
|
||||
/// @param outputToken The token being bought.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
|
||||
/// @param auxiliaryData Arbitrary auxiliary data supplied to the contract.
|
||||
/// @return boughtAmount The amount of `outputToken` bought.
|
||||
function sellEthForToken(
|
||||
address outputToken,
|
||||
address recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
emit SellEthForToken(
|
||||
outputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
address(this).balance
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Trades token for ETH. The token must be sent to the contract prior
|
||||
/// to calling this function to trigger the trade.
|
||||
/// @param inputToken The token being sold.
|
||||
/// @param recipient The recipient of the bought tokens.
|
||||
/// @param minBuyAmount The minimum acceptable amount of ETH to buy.
|
||||
/// @param auxiliaryData Arbitrary auxiliary data supplied to the contract.
|
||||
/// @return boughtAmount The amount of ETH bought.
|
||||
function sellTokenForEth(
|
||||
address inputToken,
|
||||
address payable recipient,
|
||||
uint256 minBuyAmount,
|
||||
bytes calldata auxiliaryData
|
||||
)
|
||||
external
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
emit SellTokenForEth(
|
||||
inputToken,
|
||||
recipient,
|
||||
minBuyAmount,
|
||||
IERC20TokenV06(inputToken).balanceOf(address(this))
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-zero-ex",
|
||||
"version": "0.7.0",
|
||||
"version": "0.9.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -40,9 +40,9 @@
|
||||
"publish:private": "yarn build && gitpkg publish"
|
||||
},
|
||||
"config": {
|
||||
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,SignatureValidatorFeature,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature",
|
||||
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,SignatureValidatorFeature,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProvider",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|IMetaTransactionsFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibLiquidityProviderStorage|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpender|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFullMigration|TestInitialMigration|TestLibSignature|TestLibTokenSpender|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestProtocolFees|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx).json"
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpender|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFullMigration|TestInitialMigration|TestLibSignature|TestLibTokenSpender|TestLiquidityProvider|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestProtocolFees|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -55,9 +55,9 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.7",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-gen": "2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -76,7 +76,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/subproviders": "^6.1.9",
|
||||
"@0x/types": "^3.3.0",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
|
@@ -12,6 +12,7 @@ import * as FullMigration from '../generated-artifacts/FullMigration.json';
|
||||
import * as IAllowanceTarget from '../generated-artifacts/IAllowanceTarget.json';
|
||||
import * as IERC20Transformer from '../generated-artifacts/IERC20Transformer.json';
|
||||
import * as IFlashWallet from '../generated-artifacts/IFlashWallet.json';
|
||||
import * as ILiquidityProvider from '../generated-artifacts/ILiquidityProvider.json';
|
||||
import * as InitialMigration from '../generated-artifacts/InitialMigration.json';
|
||||
import * as IOwnableFeature from '../generated-artifacts/IOwnableFeature.json';
|
||||
import * as ISimpleFunctionRegistryFeature from '../generated-artifacts/ISimpleFunctionRegistryFeature.json';
|
||||
@@ -54,4 +55,5 @@ export const artifacts = {
|
||||
LogMetadataTransformer: LogMetadataTransformer as ContractArtifact,
|
||||
BridgeAdapter: BridgeAdapter as ContractArtifact,
|
||||
LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact,
|
||||
ILiquidityProvider: ILiquidityProvider as ContractArtifact,
|
||||
};
|
||||
|
@@ -10,6 +10,7 @@ export * from '../generated-wrappers/full_migration';
|
||||
export * from '../generated-wrappers/i_allowance_target';
|
||||
export * from '../generated-wrappers/i_erc20_transformer';
|
||||
export * from '../generated-wrappers/i_flash_wallet';
|
||||
export * from '../generated-wrappers/i_liquidity_provider';
|
||||
export * from '../generated-wrappers/i_ownable_feature';
|
||||
export * from '../generated-wrappers/i_simple_function_registry_feature';
|
||||
export * from '../generated-wrappers/i_token_spender_feature';
|
||||
|
@@ -28,6 +28,7 @@ import * as IFlashWallet from '../test/generated-artifacts/IFlashWallet.json';
|
||||
import * as IGasToken from '../test/generated-artifacts/IGasToken.json';
|
||||
import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json';
|
||||
import * as ILiquidityProviderFeature from '../test/generated-artifacts/ILiquidityProviderFeature.json';
|
||||
import * as ILiquidityProviderSandbox from '../test/generated-artifacts/ILiquidityProviderSandbox.json';
|
||||
import * as IMetaTransactionsFeature from '../test/generated-artifacts/IMetaTransactionsFeature.json';
|
||||
import * as InitialMigration from '../test/generated-artifacts/InitialMigration.json';
|
||||
import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json';
|
||||
@@ -43,7 +44,6 @@ import * as LibBootstrap from '../test/generated-artifacts/LibBootstrap.json';
|
||||
import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json';
|
||||
import * as LibERC20Transformer from '../test/generated-artifacts/LibERC20Transformer.json';
|
||||
import * as LibLiquidityProviderRichErrors from '../test/generated-artifacts/LibLiquidityProviderRichErrors.json';
|
||||
import * as LibLiquidityProviderStorage from '../test/generated-artifacts/LibLiquidityProviderStorage.json';
|
||||
import * as LibMetaTransactionsRichErrors from '../test/generated-artifacts/LibMetaTransactionsRichErrors.json';
|
||||
import * as LibMetaTransactionsStorage from '../test/generated-artifacts/LibMetaTransactionsStorage.json';
|
||||
import * as LibMigrate from '../test/generated-artifacts/LibMigrate.json';
|
||||
@@ -66,6 +66,7 @@ import * as LibTransformERC20RichErrors from '../test/generated-artifacts/LibTra
|
||||
import * as LibTransformERC20Storage from '../test/generated-artifacts/LibTransformERC20Storage.json';
|
||||
import * as LibWalletRichErrors from '../test/generated-artifacts/LibWalletRichErrors.json';
|
||||
import * as LiquidityProviderFeature from '../test/generated-artifacts/LiquidityProviderFeature.json';
|
||||
import * as LiquidityProviderSandbox from '../test/generated-artifacts/LiquidityProviderSandbox.json';
|
||||
import * as LogMetadataTransformer from '../test/generated-artifacts/LogMetadataTransformer.json';
|
||||
import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransactionsFeature.json';
|
||||
import * as MixinAdapterAddresses from '../test/generated-artifacts/MixinAdapterAddresses.json';
|
||||
@@ -95,6 +96,7 @@ import * as TestFullMigration from '../test/generated-artifacts/TestFullMigratio
|
||||
import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.json';
|
||||
import * as TestLibSignature from '../test/generated-artifacts/TestLibSignature.json';
|
||||
import * as TestLibTokenSpender from '../test/generated-artifacts/TestLibTokenSpender.json';
|
||||
import * as TestLiquidityProvider from '../test/generated-artifacts/TestLiquidityProvider.json';
|
||||
import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json';
|
||||
import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
|
||||
import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json';
|
||||
@@ -137,6 +139,8 @@ export const artifacts = {
|
||||
FlashWallet: FlashWallet as ContractArtifact,
|
||||
IAllowanceTarget: IAllowanceTarget as ContractArtifact,
|
||||
IFlashWallet: IFlashWallet as ContractArtifact,
|
||||
ILiquidityProviderSandbox: ILiquidityProviderSandbox as ContractArtifact,
|
||||
LiquidityProviderSandbox: LiquidityProviderSandbox as ContractArtifact,
|
||||
TransformerDeployer: TransformerDeployer as ContractArtifact,
|
||||
BootstrapFeature: BootstrapFeature as ContractArtifact,
|
||||
IBootstrapFeature: IBootstrapFeature as ContractArtifact,
|
||||
@@ -168,7 +172,6 @@ export const artifacts = {
|
||||
InitialMigration: InitialMigration as ContractArtifact,
|
||||
LibBootstrap: LibBootstrap as ContractArtifact,
|
||||
LibMigrate: LibMigrate as ContractArtifact,
|
||||
LibLiquidityProviderStorage: LibLiquidityProviderStorage as ContractArtifact,
|
||||
LibMetaTransactionsStorage: LibMetaTransactionsStorage as ContractArtifact,
|
||||
LibOwnableStorage: LibOwnableStorage as ContractArtifact,
|
||||
LibProxyStorage: LibProxyStorage as ContractArtifact,
|
||||
@@ -217,6 +220,7 @@ export const artifacts = {
|
||||
TestInitialMigration: TestInitialMigration as ContractArtifact,
|
||||
TestLibSignature: TestLibSignature as ContractArtifact,
|
||||
TestLibTokenSpender: TestLibTokenSpender as ContractArtifact,
|
||||
TestLiquidityProvider: TestLiquidityProvider as ContractArtifact,
|
||||
TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact,
|
||||
TestMigrator: TestMigrator as ContractArtifact,
|
||||
TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact,
|
||||
|
@@ -1,16 +1,25 @@
|
||||
import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||
import { blockchainTests, constants, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||
import { blockchainTests, constants, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, OwnableRevertErrors, ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import { IOwnableFeatureContract, IZeroExContract, LiquidityProviderFeatureContract } from '../../src/wrappers';
|
||||
import { artifacts } from '../artifacts';
|
||||
import { abis } from '../utils/abis';
|
||||
import { fullMigrateAsync } from '../utils/migration';
|
||||
import { IERC20BridgeEvents, TestBridgeContract, TestWethContract } from '../wrappers';
|
||||
import {
|
||||
LiquidityProviderSandboxContract,
|
||||
TestBridgeContract,
|
||||
TestBridgeEvents,
|
||||
TestLiquidityProviderContract,
|
||||
TestLiquidityProviderEvents,
|
||||
TestWethContract,
|
||||
} from '../wrappers';
|
||||
|
||||
blockchainTests('LiquidityProvider feature', env => {
|
||||
let zeroEx: IZeroExContract;
|
||||
let feature: LiquidityProviderFeatureContract;
|
||||
let sandbox: LiquidityProviderSandboxContract;
|
||||
let liquidityProvider: TestLiquidityProviderContract;
|
||||
let token: DummyERC20TokenContract;
|
||||
let weth: TestWethContract;
|
||||
let owner: string;
|
||||
@@ -47,102 +56,112 @@ blockchainTests('LiquidityProvider feature', env => {
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
weth.address,
|
||||
zeroEx.address,
|
||||
);
|
||||
sandbox = new LiquidityProviderSandboxContract(
|
||||
await featureImpl.sandbox().callAsync(),
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
);
|
||||
await new IOwnableFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis)
|
||||
.migrate(featureImpl.address, featureImpl.migrate().getABIEncodedTransactionData(), owner)
|
||||
.awaitTransactionSuccessAsync();
|
||||
|
||||
liquidityProvider = await TestLiquidityProviderContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestLiquidityProvider,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
token.address,
|
||||
weth.address,
|
||||
);
|
||||
});
|
||||
describe('Registry', () => {
|
||||
it('`getLiquidityProviderForMarket` reverts if address is not set', async () => {
|
||||
const [xAsset, yAsset] = [randomAddress(), randomAddress()];
|
||||
let tx = feature.getLiquidityProviderForMarket(xAsset, yAsset).awaitTransactionSuccessAsync();
|
||||
expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.LiquidityProvider.NoLiquidityProviderForMarketError(xAsset, yAsset),
|
||||
);
|
||||
tx = feature.getLiquidityProviderForMarket(yAsset, xAsset).awaitTransactionSuccessAsync();
|
||||
return expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.LiquidityProvider.NoLiquidityProviderForMarketError(yAsset, xAsset),
|
||||
);
|
||||
});
|
||||
it('can set/get a liquidity provider address for a given market', async () => {
|
||||
const expectedAddress = randomAddress();
|
||||
await feature
|
||||
.setLiquidityProviderForMarket(token.address, weth.address, expectedAddress)
|
||||
.awaitTransactionSuccessAsync();
|
||||
let actualAddress = await feature.getLiquidityProviderForMarket(token.address, weth.address).callAsync();
|
||||
expect(actualAddress).to.equal(expectedAddress);
|
||||
actualAddress = await feature.getLiquidityProviderForMarket(weth.address, token.address).callAsync();
|
||||
expect(actualAddress).to.equal(expectedAddress);
|
||||
});
|
||||
it('can update a liquidity provider address for a given market', async () => {
|
||||
const expectedAddress = randomAddress();
|
||||
await feature
|
||||
.setLiquidityProviderForMarket(token.address, weth.address, expectedAddress)
|
||||
.awaitTransactionSuccessAsync();
|
||||
let actualAddress = await feature.getLiquidityProviderForMarket(token.address, weth.address).callAsync();
|
||||
expect(actualAddress).to.equal(expectedAddress);
|
||||
actualAddress = await feature.getLiquidityProviderForMarket(weth.address, token.address).callAsync();
|
||||
expect(actualAddress).to.equal(expectedAddress);
|
||||
});
|
||||
it('can effectively remove a liquidity provider for a market by setting the address to 0', async () => {
|
||||
await feature
|
||||
.setLiquidityProviderForMarket(token.address, weth.address, constants.NULL_ADDRESS)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const tx = feature
|
||||
.getLiquidityProviderForMarket(token.address, weth.address)
|
||||
.awaitTransactionSuccessAsync();
|
||||
return expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.LiquidityProvider.NoLiquidityProviderForMarketError(token.address, weth.address),
|
||||
);
|
||||
});
|
||||
it('reverts if non-owner attempts to set an address', async () => {
|
||||
const tx = feature
|
||||
.setLiquidityProviderForMarket(randomAddress(), randomAddress(), randomAddress())
|
||||
blockchainTests.resets('Sandbox', () => {
|
||||
it('Cannot call sandbox `executeSellTokenForToken` function directly', async () => {
|
||||
const tx = sandbox
|
||||
.executeSellTokenForToken(
|
||||
liquidityProvider.address,
|
||||
token.address,
|
||||
weth.address,
|
||||
taker,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker, owner));
|
||||
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker));
|
||||
});
|
||||
it('Cannot call sandbox `executeSellEthForToken` function directly', async () => {
|
||||
const tx = sandbox
|
||||
.executeSellEthForToken(
|
||||
liquidityProvider.address,
|
||||
token.address,
|
||||
taker,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker));
|
||||
});
|
||||
it('Cannot call sandbox `executeSellTokenForEth` function directly', async () => {
|
||||
const tx = sandbox
|
||||
.executeSellTokenForEth(
|
||||
liquidityProvider.address,
|
||||
token.address,
|
||||
taker,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker));
|
||||
});
|
||||
});
|
||||
blockchainTests.resets('Swap', () => {
|
||||
let liquidityProvider: TestBridgeContract;
|
||||
const ETH_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
||||
|
||||
before(async () => {
|
||||
liquidityProvider = await TestBridgeContract.deployFrom0xArtifactAsync(
|
||||
it('Successfully executes an ERC20-ERC20 swap', async () => {
|
||||
const tx = await feature
|
||||
.sellToLiquidityProvider(
|
||||
token.address,
|
||||
weth.address,
|
||||
liquidityProvider.address,
|
||||
constants.NULL_ADDRESS,
|
||||
constants.ONE_ETHER,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
verifyEventsFromLogs(
|
||||
tx.logs,
|
||||
[
|
||||
{
|
||||
inputToken: token.address,
|
||||
outputToken: weth.address,
|
||||
recipient: taker,
|
||||
minBuyAmount: constants.ZERO_AMOUNT,
|
||||
inputTokenBalance: constants.ONE_ETHER,
|
||||
},
|
||||
],
|
||||
TestLiquidityProviderEvents.SellTokenForToken,
|
||||
);
|
||||
});
|
||||
it('Successfully executes an ERC20-ERC20 swap (backwards-compatibility)', async () => {
|
||||
const bridge = await TestBridgeContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestBridge,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
token.address,
|
||||
weth.address,
|
||||
token.address,
|
||||
);
|
||||
await feature
|
||||
.setLiquidityProviderForMarket(token.address, weth.address, liquidityProvider.address)
|
||||
.awaitTransactionSuccessAsync();
|
||||
});
|
||||
it('Cannot execute a swap for a market without a liquidity provider set', async () => {
|
||||
const [xAsset, yAsset] = [randomAddress(), randomAddress()];
|
||||
const tx = feature
|
||||
.sellToLiquidityProvider(
|
||||
xAsset,
|
||||
yAsset,
|
||||
constants.NULL_ADDRESS,
|
||||
constants.ONE_ETHER,
|
||||
constants.ZERO_AMOUNT,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
return expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.LiquidityProvider.NoLiquidityProviderForMarketError(xAsset, yAsset),
|
||||
);
|
||||
});
|
||||
it('Successfully executes an ERC20-ERC20 swap', async () => {
|
||||
const tx = await feature
|
||||
.sellToLiquidityProvider(
|
||||
weth.address,
|
||||
token.address,
|
||||
weth.address,
|
||||
bridge.address,
|
||||
constants.NULL_ADDRESS,
|
||||
constants.ONE_ETHER,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
verifyEventsFromLogs(
|
||||
@@ -153,22 +172,24 @@ blockchainTests('LiquidityProvider feature', env => {
|
||||
outputToken: weth.address,
|
||||
inputTokenAmount: constants.ONE_ETHER,
|
||||
outputTokenAmount: constants.ZERO_AMOUNT,
|
||||
from: constants.NULL_ADDRESS,
|
||||
from: bridge.address,
|
||||
to: taker,
|
||||
},
|
||||
],
|
||||
IERC20BridgeEvents.ERC20BridgeTransfer,
|
||||
TestBridgeEvents.ERC20BridgeTransfer,
|
||||
);
|
||||
});
|
||||
it('Reverts if cannot fulfill the minimum buy amount', async () => {
|
||||
const minBuyAmount = new BigNumber(1);
|
||||
const tx = feature
|
||||
.sellToLiquidityProvider(
|
||||
weth.address,
|
||||
token.address,
|
||||
weth.address,
|
||||
liquidityProvider.address,
|
||||
constants.NULL_ADDRESS,
|
||||
constants.ONE_ETHER,
|
||||
minBuyAmount,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
return expect(tx).to.revertWith(
|
||||
@@ -185,36 +206,38 @@ blockchainTests('LiquidityProvider feature', env => {
|
||||
it('Successfully executes an ETH-ERC20 swap', async () => {
|
||||
const tx = await feature
|
||||
.sellToLiquidityProvider(
|
||||
token.address,
|
||||
ETH_TOKEN_ADDRESS,
|
||||
token.address,
|
||||
liquidityProvider.address,
|
||||
constants.NULL_ADDRESS,
|
||||
constants.ONE_ETHER,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker, value: constants.ONE_ETHER });
|
||||
verifyEventsFromLogs(
|
||||
tx.logs,
|
||||
[
|
||||
{
|
||||
inputToken: weth.address,
|
||||
outputToken: token.address,
|
||||
inputTokenAmount: constants.ONE_ETHER,
|
||||
outputTokenAmount: constants.ZERO_AMOUNT,
|
||||
from: constants.NULL_ADDRESS,
|
||||
to: taker,
|
||||
recipient: taker,
|
||||
minBuyAmount: constants.ZERO_AMOUNT,
|
||||
ethBalance: constants.ONE_ETHER,
|
||||
},
|
||||
],
|
||||
IERC20BridgeEvents.ERC20BridgeTransfer,
|
||||
TestLiquidityProviderEvents.SellEthForToken,
|
||||
);
|
||||
});
|
||||
it('Successfully executes an ERC20-ETH swap', async () => {
|
||||
const tx = await feature
|
||||
.sellToLiquidityProvider(
|
||||
ETH_TOKEN_ADDRESS,
|
||||
token.address,
|
||||
ETH_TOKEN_ADDRESS,
|
||||
liquidityProvider.address,
|
||||
constants.NULL_ADDRESS,
|
||||
constants.ONE_ETHER,
|
||||
constants.ZERO_AMOUNT,
|
||||
constants.NULL_BYTES,
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
verifyEventsFromLogs(
|
||||
@@ -222,14 +245,12 @@ blockchainTests('LiquidityProvider feature', env => {
|
||||
[
|
||||
{
|
||||
inputToken: token.address,
|
||||
outputToken: weth.address,
|
||||
inputTokenAmount: constants.ONE_ETHER,
|
||||
outputTokenAmount: constants.ZERO_AMOUNT,
|
||||
from: constants.NULL_ADDRESS,
|
||||
to: zeroEx.address,
|
||||
recipient: taker,
|
||||
minBuyAmount: constants.ZERO_AMOUNT,
|
||||
inputTokenBalance: constants.ONE_ETHER,
|
||||
},
|
||||
],
|
||||
IERC20BridgeEvents.ERC20BridgeTransfer,
|
||||
TestLiquidityProviderEvents.SellTokenForEth,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -66,7 +66,7 @@ blockchainTests.resets('SimpleFunctionRegistry feature', env => {
|
||||
|
||||
it('`rollback()` to zero impl succeeds for unregistered function', async () => {
|
||||
await registry.rollback(testFnSelector, NULL_ADDRESS).awaitTransactionSuccessAsync();
|
||||
const impl = await zeroEx.getFunctionImplementation(testFnSelector).callAsync();
|
||||
const impl = await registry.getFunctionImplementation(testFnSelector).callAsync();
|
||||
expect(impl).to.eq(NULL_ADDRESS);
|
||||
});
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import {
|
||||
IMetaTransactionsFeatureContract,
|
||||
IOwnableFeatureContract,
|
||||
ISignatureValidatorFeatureContract,
|
||||
ISimpleFunctionRegistryFeatureContract,
|
||||
ITokenSpenderFeatureContract,
|
||||
ITransformERC20FeatureContract,
|
||||
TestFullMigrationContract,
|
||||
@@ -25,6 +26,7 @@ blockchainTests.resets('Full migration', env => {
|
||||
let zeroEx: ZeroExContract;
|
||||
let features: FullFeatures;
|
||||
let migrator: TestFullMigrationContract;
|
||||
let registry: ISimpleFunctionRegistryFeatureContract;
|
||||
const transformerDeployer = randomAddress();
|
||||
|
||||
before(async () => {
|
||||
@@ -47,6 +49,7 @@ blockchainTests.resets('Full migration', env => {
|
||||
await migrator
|
||||
.initializeZeroEx(owner, zeroEx.address, features, { transformerDeployer })
|
||||
.awaitTransactionSuccessAsync();
|
||||
registry = new ISimpleFunctionRegistryFeatureContract(zeroEx.address, env.provider, env.txDefaults);
|
||||
});
|
||||
|
||||
it('ZeroEx has the correct owner', async () => {
|
||||
@@ -157,7 +160,7 @@ blockchainTests.resets('Full migration', env => {
|
||||
for (const fn of featureInfo.fns) {
|
||||
it(`${fn} is registered`, async () => {
|
||||
const selector = contract.getSelector(fn);
|
||||
const impl = await zeroEx.getFunctionImplementation(selector).callAsync();
|
||||
const impl = await registry.getFunctionImplementation(selector).callAsync();
|
||||
expect(impl).to.not.eq(NULL_ADDRESS);
|
||||
});
|
||||
|
||||
|
@@ -1,17 +1,19 @@
|
||||
import { blockchainTests, constants, expect } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, hexUtils } from '@0x/utils';
|
||||
import { AuthorizableRevertErrors, BigNumber, hexUtils, ZeroExRevertErrors } from '@0x/utils';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { TestProtocolFeesContract, TestStakingContract, TestWethContract } from './wrappers';
|
||||
import { FeeCollectorContract, TestProtocolFeesContract, TestStakingContract, TestWethContract } from './wrappers';
|
||||
|
||||
blockchainTests.resets('ProtocolFees', env => {
|
||||
let payer: string;
|
||||
let unauthorized: string;
|
||||
let protocolFees: TestProtocolFeesContract;
|
||||
let staking: TestStakingContract;
|
||||
let weth: TestWethContract;
|
||||
|
||||
before(async () => {
|
||||
[payer] = await env.getAccountAddressesAsync();
|
||||
[payer, unauthorized] = await env.getAccountAddressesAsync();
|
||||
protocolFees = await TestProtocolFeesContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestProtocolFees,
|
||||
env.provider,
|
||||
@@ -35,41 +37,128 @@ blockchainTests.resets('ProtocolFees', env => {
|
||||
await weth.approve(protocolFees.address, constants.ONE_ETHER).awaitTransactionSuccessAsync({ from: payer });
|
||||
});
|
||||
|
||||
async function collectAsync(
|
||||
poolId: string,
|
||||
amount: BigNumber,
|
||||
etherValue: BigNumber,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
return protocolFees
|
||||
.collectProtocolFee(poolId, amount, weth.address)
|
||||
.awaitTransactionSuccessAsync({ from: payer, value: etherValue });
|
||||
}
|
||||
|
||||
async function transferFeesAsync(poolId: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
return protocolFees.transferFeesForPool(poolId, staking.address, weth.address).awaitTransactionSuccessAsync();
|
||||
}
|
||||
|
||||
describe('FeeCollector', () => {
|
||||
it('should disallow unauthorized initialization', async () => {
|
||||
const pool = hexUtils.random();
|
||||
|
||||
await collectAsync(pool, constants.ONE_ETHER, constants.ZERO_AMOUNT);
|
||||
await transferFeesAsync(pool);
|
||||
|
||||
const feeCollector = new FeeCollectorContract(
|
||||
await protocolFees.getFeeCollector(pool).callAsync(),
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
);
|
||||
|
||||
const tx = feeCollector
|
||||
.initialize(weth.address, staking.address, pool)
|
||||
.sendTransactionAsync({ from: unauthorized });
|
||||
return expect(tx).to.revertWith(new AuthorizableRevertErrors.SenderNotAuthorizedError(unauthorized));
|
||||
});
|
||||
});
|
||||
|
||||
describe('_collectProtocolFee()', () => {
|
||||
it('can collect a protocol fee multiple times', async () => {
|
||||
const poolId = hexUtils.random();
|
||||
const amount1 = new BigNumber(123456);
|
||||
const amount2 = new BigNumber(456789);
|
||||
const pool1 = hexUtils.random();
|
||||
const pool2 = hexUtils.random();
|
||||
|
||||
// Transfer amount1 via WETH.
|
||||
await protocolFees
|
||||
.collectProtocolFee(poolId, amount1, weth.address)
|
||||
.awaitTransactionSuccessAsync({ from: payer });
|
||||
it('should revert if WETH transfer fails', async () => {
|
||||
const tooMuch = constants.ONE_ETHER.plus(1);
|
||||
const tx = collectAsync(pool1, constants.ONE_ETHER.plus(1), constants.ZERO_AMOUNT);
|
||||
return expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.Spender.SpenderERC20TransferFromFailedError(
|
||||
weth.address,
|
||||
payer,
|
||||
undefined,
|
||||
tooMuch,
|
||||
undefined,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
// Send to staking contract.
|
||||
await protocolFees
|
||||
.transferFeesForPool(poolId, staking.address, weth.address)
|
||||
.awaitTransactionSuccessAsync();
|
||||
it('should revert if insufficient ETH transferred', async () => {
|
||||
const tooLittle = constants.ONE_ETHER.minus(1);
|
||||
const tx = collectAsync(pool1, constants.ONE_ETHER, tooLittle);
|
||||
return expect(tx).to.revertWith('FixinProtocolFees/ETHER_TRANSFER_FALIED');
|
||||
});
|
||||
|
||||
// Transfer amount2 via ETH.
|
||||
await protocolFees
|
||||
.collectProtocolFee(poolId, amount2, weth.address)
|
||||
.awaitTransactionSuccessAsync({ from: payer, value: amount2 });
|
||||
it('should accept WETH fee', async () => {
|
||||
const beforeWETH = await weth.balanceOf(payer).callAsync();
|
||||
await collectAsync(pool1, constants.ONE_ETHER, constants.ZERO_AMOUNT);
|
||||
const afterWETH = await weth.balanceOf(payer).callAsync();
|
||||
|
||||
// Send to staking contract again.
|
||||
await protocolFees
|
||||
.transferFeesForPool(poolId, staking.address, weth.address)
|
||||
.awaitTransactionSuccessAsync();
|
||||
return expect(beforeWETH.minus(afterWETH)).to.bignumber.eq(constants.ONE_ETHER);
|
||||
});
|
||||
|
||||
const balance = await staking.balanceForPool(poolId).callAsync();
|
||||
const wethBalance = await weth.balanceOf(staking.address).callAsync();
|
||||
it('should accept ETH fee', async () => {
|
||||
const beforeWETH = await weth.balanceOf(payer).callAsync();
|
||||
const beforeETH = await env.web3Wrapper.getBalanceInWeiAsync(payer);
|
||||
await collectAsync(pool1, constants.ONE_ETHER, constants.ONE_ETHER);
|
||||
const afterWETH = await weth.balanceOf(payer).callAsync();
|
||||
const afterETH = await env.web3Wrapper.getBalanceInWeiAsync(payer);
|
||||
|
||||
// Check that staking accounted for the collected ether properly.
|
||||
expect(balance).to.bignumber.eq(wethBalance);
|
||||
// We check for greater than 1 ether spent to allow for spending on gas.
|
||||
await expect(beforeETH.minus(afterETH)).to.bignumber.gt(constants.ONE_ETHER);
|
||||
return expect(beforeWETH).to.bignumber.eq(afterWETH);
|
||||
});
|
||||
|
||||
// We leave 1 wei behind, of both ETH and WETH, for gas reasons.
|
||||
const total = amount1.plus(amount2).minus(2);
|
||||
return expect(balance).to.bignumber.eq(total);
|
||||
it('should transfer both ETH and WETH', async () => {
|
||||
await collectAsync(pool1, constants.ONE_ETHER, constants.ZERO_AMOUNT);
|
||||
await collectAsync(pool1, constants.ONE_ETHER, constants.ONE_ETHER);
|
||||
await transferFeesAsync(pool1);
|
||||
|
||||
const balanceWETH = await weth.balanceOf(staking.address).callAsync();
|
||||
|
||||
// We leave 1 wei behind of both ETH and WETH.
|
||||
return expect(balanceWETH).to.bignumber.eq(constants.ONE_ETHER.times(2).minus(2));
|
||||
});
|
||||
|
||||
it('should accept ETH after first transfer', async () => {
|
||||
await collectAsync(pool1, constants.ONE_ETHER, constants.ONE_ETHER);
|
||||
await transferFeesAsync(pool1);
|
||||
await collectAsync(pool1, constants.ONE_ETHER, constants.ONE_ETHER);
|
||||
await transferFeesAsync(pool1);
|
||||
|
||||
const balanceWETH = await weth.balanceOf(staking.address).callAsync();
|
||||
|
||||
// We leave 1 wei behind of both ETH and WETH
|
||||
return expect(balanceWETH).to.bignumber.eq(constants.ONE_ETHER.times(2).minus(2));
|
||||
});
|
||||
|
||||
it('should attribute fees correctly', async () => {
|
||||
const pool1Amount = new BigNumber(12345);
|
||||
const pool2Amount = new BigNumber(45678);
|
||||
|
||||
await collectAsync(pool1, pool1Amount, pool1Amount); // ETH
|
||||
await transferFeesAsync(pool1);
|
||||
await collectAsync(pool2, pool2Amount, constants.ZERO_AMOUNT); // WETH
|
||||
await transferFeesAsync(pool2);
|
||||
|
||||
const pool1Balance = await staking.balanceForPool(pool1).callAsync();
|
||||
const pool2Balance = await staking.balanceForPool(pool2).callAsync();
|
||||
|
||||
const balanceWETH = await weth.balanceOf(staking.address).callAsync();
|
||||
|
||||
await expect(balanceWETH).to.bignumber.equal(pool1Balance.plus(pool2Balance));
|
||||
|
||||
// We leave 1 wei behind of both ETH and WETH.
|
||||
await expect(pool1Balance).to.bignumber.equal(pool1Amount.minus(2));
|
||||
|
||||
// Here we paid in WETH, so there's just 1 wei of WETH held back.
|
||||
return expect(pool2Balance).to.bignumber.equal(pool2Amount.minus(1));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -26,6 +26,7 @@ export * from '../test/generated-wrappers/i_flash_wallet';
|
||||
export * from '../test/generated-wrappers/i_gas_token';
|
||||
export * from '../test/generated-wrappers/i_liquidity_provider';
|
||||
export * from '../test/generated-wrappers/i_liquidity_provider_feature';
|
||||
export * from '../test/generated-wrappers/i_liquidity_provider_sandbox';
|
||||
export * from '../test/generated-wrappers/i_meta_transactions_feature';
|
||||
export * from '../test/generated-wrappers/i_ownable_feature';
|
||||
export * from '../test/generated-wrappers/i_signature_validator_feature';
|
||||
@@ -41,7 +42,6 @@ export * from '../test/generated-wrappers/lib_bootstrap';
|
||||
export * from '../test/generated-wrappers/lib_common_rich_errors';
|
||||
export * from '../test/generated-wrappers/lib_erc20_transformer';
|
||||
export * from '../test/generated-wrappers/lib_liquidity_provider_rich_errors';
|
||||
export * from '../test/generated-wrappers/lib_liquidity_provider_storage';
|
||||
export * from '../test/generated-wrappers/lib_meta_transactions_rich_errors';
|
||||
export * from '../test/generated-wrappers/lib_meta_transactions_storage';
|
||||
export * from '../test/generated-wrappers/lib_migrate';
|
||||
@@ -64,6 +64,7 @@ export * from '../test/generated-wrappers/lib_transform_erc20_rich_errors';
|
||||
export * from '../test/generated-wrappers/lib_transform_erc20_storage';
|
||||
export * from '../test/generated-wrappers/lib_wallet_rich_errors';
|
||||
export * from '../test/generated-wrappers/liquidity_provider_feature';
|
||||
export * from '../test/generated-wrappers/liquidity_provider_sandbox';
|
||||
export * from '../test/generated-wrappers/log_metadata_transformer';
|
||||
export * from '../test/generated-wrappers/meta_transactions_feature';
|
||||
export * from '../test/generated-wrappers/mixin_adapter_addresses';
|
||||
@@ -93,6 +94,7 @@ export * from '../test/generated-wrappers/test_full_migration';
|
||||
export * from '../test/generated-wrappers/test_initial_migration';
|
||||
export * from '../test/generated-wrappers/test_lib_signature';
|
||||
export * from '../test/generated-wrappers/test_lib_token_spender';
|
||||
export * from '../test/generated-wrappers/test_liquidity_provider';
|
||||
export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature';
|
||||
export * from '../test/generated-wrappers/test_migrator';
|
||||
export * from '../test/generated-wrappers/test_mint_token_erc20_transformer';
|
||||
|
@@ -83,7 +83,7 @@ blockchainTests.resets('ZeroEx contract', env => {
|
||||
// registry.getSelector('extendSelf'),
|
||||
];
|
||||
const selectors = [...ownableSelectors, ...registrySelectors];
|
||||
const impls = await Promise.all(selectors.map(s => zeroEx.getFunctionImplementation(s).callAsync()));
|
||||
const impls = await Promise.all(selectors.map(s => registry.getFunctionImplementation(s).callAsync()));
|
||||
for (let i = 0; i < impls.length; ++i) {
|
||||
const selector = selectors[i];
|
||||
const impl = impls[i];
|
||||
|
@@ -10,6 +10,7 @@
|
||||
"generated-artifacts/IAllowanceTarget.json",
|
||||
"generated-artifacts/IERC20Transformer.json",
|
||||
"generated-artifacts/IFlashWallet.json",
|
||||
"generated-artifacts/ILiquidityProvider.json",
|
||||
"generated-artifacts/IOwnableFeature.json",
|
||||
"generated-artifacts/ISimpleFunctionRegistryFeature.json",
|
||||
"generated-artifacts/ITokenSpenderFeature.json",
|
||||
@@ -50,6 +51,7 @@
|
||||
"test/generated-artifacts/IGasToken.json",
|
||||
"test/generated-artifacts/ILiquidityProvider.json",
|
||||
"test/generated-artifacts/ILiquidityProviderFeature.json",
|
||||
"test/generated-artifacts/ILiquidityProviderSandbox.json",
|
||||
"test/generated-artifacts/IMetaTransactionsFeature.json",
|
||||
"test/generated-artifacts/IOwnableFeature.json",
|
||||
"test/generated-artifacts/ISignatureValidatorFeature.json",
|
||||
@@ -65,7 +67,6 @@
|
||||
"test/generated-artifacts/LibCommonRichErrors.json",
|
||||
"test/generated-artifacts/LibERC20Transformer.json",
|
||||
"test/generated-artifacts/LibLiquidityProviderRichErrors.json",
|
||||
"test/generated-artifacts/LibLiquidityProviderStorage.json",
|
||||
"test/generated-artifacts/LibMetaTransactionsRichErrors.json",
|
||||
"test/generated-artifacts/LibMetaTransactionsStorage.json",
|
||||
"test/generated-artifacts/LibMigrate.json",
|
||||
@@ -88,6 +89,7 @@
|
||||
"test/generated-artifacts/LibTransformERC20Storage.json",
|
||||
"test/generated-artifacts/LibWalletRichErrors.json",
|
||||
"test/generated-artifacts/LiquidityProviderFeature.json",
|
||||
"test/generated-artifacts/LiquidityProviderSandbox.json",
|
||||
"test/generated-artifacts/LogMetadataTransformer.json",
|
||||
"test/generated-artifacts/MetaTransactionsFeature.json",
|
||||
"test/generated-artifacts/MixinAdapterAddresses.json",
|
||||
@@ -117,6 +119,7 @@
|
||||
"test/generated-artifacts/TestInitialMigration.json",
|
||||
"test/generated-artifacts/TestLibSignature.json",
|
||||
"test/generated-artifacts/TestLibTokenSpender.json",
|
||||
"test/generated-artifacts/TestLiquidityProvider.json",
|
||||
"test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json",
|
||||
"test/generated-artifacts/TestMigrator.json",
|
||||
"test/generated-artifacts/TestMintTokenERC20Transformer.json",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"version": "5.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add support for LiquidityProvider feature in the swap quote consumer",
|
||||
"pr": 16
|
||||
},
|
||||
{
|
||||
"note": "Remove support for MultiBridge 😞",
|
||||
"pr": 16
|
||||
}
|
||||
],
|
||||
"timestamp": 1605302002
|
||||
},
|
||||
{
|
||||
"timestamp": 1604620645,
|
||||
"version": "5.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604385937,
|
||||
"version": "5.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
},
|
||||
{
|
||||
"note": "adding Curve pools: PAX, hBTC, metapools: gUSD, hUSD, USDn, mUSD, tBTC",
|
||||
"pr": 26
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1604376968,
|
||||
"version": "5.0.1",
|
||||
|
@@ -5,6 +5,20 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v5.1.0 - _November 13, 2020_
|
||||
|
||||
* Add support for LiquidityProvider feature in the swap quote consumer (#16)
|
||||
* Remove support for MultiBridge 😞 (#16)
|
||||
|
||||
## v5.0.3 - _November 5, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.0.2 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
* adding Curve pools: PAX, hBTC, metapools: gUSD, hUSD, USDn, mUSD, tBTC (#26)
|
||||
|
||||
## v5.0.1 - _November 3, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -20,8 +20,7 @@ pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
import "./interfaces/ILiquidityProvider.sol";
|
||||
import "./interfaces/ILiquidityProviderRegistry.sol";
|
||||
import "@0x/contracts-zero-ex/contracts/src/vendor/ILiquidityProvider.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
|
||||
@@ -34,37 +33,26 @@ contract LiquidityProviderSampler is
|
||||
uint256 constant private DEFAULT_CALL_GAS = 400e3; // 400k
|
||||
|
||||
/// @dev Sample sell quotes from an arbitrary on-chain liquidity provider.
|
||||
/// @param registryAddress Address of the liquidity provider registry contract.
|
||||
/// @param providerAddress Address of the liquidity provider.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromLiquidityProviderRegistry(
|
||||
address registryAddress,
|
||||
function sampleSellsFromLiquidityProvider(
|
||||
address providerAddress,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts, address providerAddress)
|
||||
returns (uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
// Initialize array of maker token amounts.
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
|
||||
// Query registry for provider address.
|
||||
providerAddress = _getLiquidityProviderFromRegistry(
|
||||
registryAddress,
|
||||
takerToken,
|
||||
makerToken
|
||||
);
|
||||
// If provider doesn't exist, return all zeros.
|
||||
if (providerAddress == address(0)) {
|
||||
return (makerTokenAmounts, providerAddress);
|
||||
}
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
try
|
||||
ILiquidityProvider(providerAddress).getSellQuote
|
||||
@@ -81,68 +69,33 @@ contract LiquidityProviderSampler is
|
||||
}
|
||||
|
||||
/// @dev Sample buy quotes from an arbitrary on-chain liquidity provider.
|
||||
/// @param registryAddress Address of the liquidity provider registry contract.
|
||||
/// @param providerAddress Address of the liquidity provider.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function sampleBuysFromLiquidityProviderRegistry(
|
||||
address registryAddress,
|
||||
function sampleBuysFromLiquidityProvider(
|
||||
address providerAddress,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory makerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory takerTokenAmounts, address providerAddress)
|
||||
returns (uint256[] memory takerTokenAmounts)
|
||||
{
|
||||
providerAddress = _getLiquidityProviderFromRegistry(
|
||||
registryAddress,
|
||||
takerToken,
|
||||
makerToken
|
||||
);
|
||||
takerTokenAmounts = _sampleApproximateBuys(
|
||||
ApproximateBuyQuoteOpts({
|
||||
makerTokenData: abi.encode(makerToken, registryAddress),
|
||||
takerTokenData: abi.encode(takerToken, registryAddress),
|
||||
getSellQuoteCallback: _sampleSellForApproximateBuyFromLiquidityProviderRegistry
|
||||
makerTokenData: abi.encode(makerToken, providerAddress),
|
||||
takerTokenData: abi.encode(takerToken, providerAddress),
|
||||
getSellQuoteCallback: _sampleSellForApproximateBuyFromLiquidityProvider
|
||||
}),
|
||||
makerTokenAmounts
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Returns the address of a liquidity provider for the given market
|
||||
/// (takerToken, makerToken), from a registry of liquidity providers.
|
||||
/// Returns address(0) if no such provider exists in the registry.
|
||||
/// @param takerToken Taker asset managed by liquidity provider.
|
||||
/// @param makerToken Maker asset managed by liquidity provider.
|
||||
/// @return providerAddress Address of the liquidity provider.
|
||||
function _getLiquidityProviderFromRegistry(
|
||||
address registryAddress,
|
||||
address takerToken,
|
||||
address makerToken
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (address providerAddress)
|
||||
{
|
||||
if (registryAddress == address(0)) {
|
||||
return address(0);
|
||||
}
|
||||
|
||||
bytes memory callData = abi.encodeWithSelector(
|
||||
ILiquidityProviderRegistry.getLiquidityProviderForMarket.selector,
|
||||
takerToken,
|
||||
makerToken
|
||||
);
|
||||
(bool didSucceed, bytes memory returnData) = registryAddress.staticcall(callData);
|
||||
if (didSucceed && returnData.length == 32) {
|
||||
return LibBytesV06.readAddress(returnData, 12);
|
||||
}
|
||||
}
|
||||
|
||||
function _sampleSellForApproximateBuyFromLiquidityProviderRegistry(
|
||||
function _sampleSellForApproximateBuyFromLiquidityProvider(
|
||||
bytes memory takerTokenData,
|
||||
bytes memory makerTokenData,
|
||||
uint256 sellAmount
|
||||
@@ -151,15 +104,15 @@ contract LiquidityProviderSampler is
|
||||
view
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
(address takerToken, address plpRegistryAddress) =
|
||||
(address takerToken, address providerAddress) =
|
||||
abi.decode(takerTokenData, (address, address));
|
||||
(address makerToken) =
|
||||
abi.decode(makerTokenData, (address));
|
||||
try
|
||||
this.sampleSellsFromLiquidityProviderRegistry
|
||||
this.sampleSellsFromLiquidityProvider
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(plpRegistryAddress, takerToken, makerToken, _toSingleValueArray(sellAmount))
|
||||
returns (uint256[] memory amounts, address)
|
||||
(providerAddress, takerToken, makerToken, _toSingleValueArray(sellAmount))
|
||||
returns (uint256[] memory amounts)
|
||||
{
|
||||
return amounts[0];
|
||||
} catch (bytes memory) {
|
||||
|
@@ -1,70 +0,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;
|
||||
|
||||
|
||||
interface ILiquidityProvider {
|
||||
|
||||
/// @dev Transfers `amount` of the ERC20 `tokenAddress` from `from` to `to`.
|
||||
/// @param tokenAddress The address of the ERC20 token to transfer.
|
||||
/// @param from Address to transfer asset from.
|
||||
/// @param to Address to transfer asset to.
|
||||
/// @param amount Amount of asset to transfer.
|
||||
/// @param bridgeData Arbitrary asset data needed by the bridge contract.
|
||||
/// @return success The magic bytes `0xdc1600f3` if successful.
|
||||
function bridgeTransferFrom(
|
||||
address tokenAddress,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata bridgeData
|
||||
)
|
||||
external
|
||||
returns (bytes4 success);
|
||||
|
||||
/// @dev Quotes the amount of `makerToken` that would be obtained by
|
||||
/// selling `sellAmount` of `takerToken`.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @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);
|
||||
|
||||
/// @dev Quotes the amount of `takerToken` that would need to be sold in
|
||||
/// order to obtain `buyAmount` of `makerToken`.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @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);
|
||||
}
|
@@ -1,36 +0,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;
|
||||
|
||||
|
||||
interface ILiquidityProviderRegistry {
|
||||
|
||||
/// @dev Returns the address of a liquidity provider for the given market
|
||||
/// (takerToken, makerToken), reverting if the pool does not exist.
|
||||
/// @param takerToken Taker asset managed by liquidity provider.
|
||||
/// @param makerToken Maker asset managed by liquidity provider.
|
||||
/// @return providerAddress Address of the liquidity provider.
|
||||
function getLiquidityProviderForMarket(
|
||||
address takerToken,
|
||||
address makerToken
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address providerAddress);
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
contract DummyLiquidityProviderRegistry
|
||||
{
|
||||
address private constant NULL_ADDRESS = address(0x0);
|
||||
|
||||
mapping (address => mapping (address => address)) internal _gAddressBook;
|
||||
|
||||
/// @dev Sets address of pool for a market given market (xAsset, yAsset).
|
||||
/// @param xToken First asset managed by pool.
|
||||
/// @param yToken Second asset managed by pool.
|
||||
/// @param poolAddress Address of pool.
|
||||
function setLiquidityProviderForMarket(
|
||||
address xToken,
|
||||
address yToken,
|
||||
address poolAddress
|
||||
)
|
||||
external
|
||||
{
|
||||
_gAddressBook[xToken][yToken] = poolAddress;
|
||||
_gAddressBook[yToken][xToken] = poolAddress;
|
||||
}
|
||||
|
||||
/// @dev Returns the address of pool for a market given market (xAsset, yAsset), or reverts if pool does not exist.
|
||||
/// @param xToken First asset managed by pool.
|
||||
/// @param yToken Second asset managed by pool.
|
||||
/// @return poolAddress Address of pool.
|
||||
function getLiquidityProviderForMarket(
|
||||
address xToken,
|
||||
address yToken
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address poolAddress)
|
||||
{
|
||||
poolAddress = _gAddressBook[xToken][yToken];
|
||||
require(
|
||||
poolAddress != NULL_ADDRESS,
|
||||
"Registry/MARKET_PAIR_NOT_SET"
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/asset-swapper",
|
||||
"version": "5.0.1",
|
||||
"version": "5.1.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -36,9 +36,9 @@
|
||||
"publish:private": "yarn build && gitpkg publish"
|
||||
},
|
||||
"config": {
|
||||
"publicInterfaceContracts": "ERC20BridgeSampler,ILiquidityProvider,ILiquidityProviderRegistry,DummyLiquidityProviderRegistry,DummyLiquidityProvider",
|
||||
"publicInterfaceContracts": "ERC20BridgeSampler",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalancerSampler|CurveSampler|DODOSampler|DeploymentConstants|DummyLiquidityProvider|DummyLiquidityProviderRegistry|ERC20BridgeSampler|Eth2DaiSampler|IBalancer|ICurve|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SushiSwapSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler).json",
|
||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalancerSampler|CurveSampler|DODOSampler|DeploymentConstants|DummyLiquidityProvider|ERC20BridgeSampler|Eth2DaiSampler|IBalancer|ICurve|IEth2Dai|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SushiSwapSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler).json",
|
||||
"postpublish": {
|
||||
"assets": []
|
||||
}
|
||||
@@ -59,11 +59,11 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.17",
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contract-addresses": "^5.1.0",
|
||||
"@0x/contract-wrappers": "^13.9.4",
|
||||
"@0x/contract-addresses": "^5.3.0",
|
||||
"@0x/contract-wrappers": "^13.10.0",
|
||||
"@0x/dev-utils": "^4.0.1",
|
||||
"@0x/json-schemas": "^5.3.3",
|
||||
"@0x/order-utils": "^10.4.4",
|
||||
"@0x/order-utils": "^10.4.6",
|
||||
"@0x/orderbook": "^2.2.7",
|
||||
"@0x/quote-server": "^3.1.0",
|
||||
"@0x/types": "^3.3.0",
|
||||
@@ -87,15 +87,16 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/base-contract": "^6.2.11",
|
||||
"@0x/contracts-asset-proxy": "^3.6.3",
|
||||
"@0x/contracts-erc20": "^3.2.6",
|
||||
"@0x/contracts-exchange": "^3.2.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.12",
|
||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
||||
"@0x/contracts-erc20": "^3.2.8",
|
||||
"@0x/contracts-exchange": "^3.2.14",
|
||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
||||
"@0x/contracts-gen": "^2.0.18",
|
||||
"@0x/contracts-test-utils": "^5.3.9",
|
||||
"@0x/contracts-utils": "^4.5.6",
|
||||
"@0x/contracts-test-utils": "^5.3.11",
|
||||
"@0x/contracts-utils": "^4.5.8",
|
||||
"@0x/contracts-zero-ex": "^0.9.0",
|
||||
"@0x/mesh-rpc-client": "^9.4.2",
|
||||
"@0x/migrations": "^6.4.6",
|
||||
"@0x/migrations": "^6.5.0",
|
||||
"@0x/sol-compiler": "^4.2.7",
|
||||
"@0x/subproviders": "^6.1.9",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -5,15 +5,5 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as DummyLiquidityProvider from '../generated-artifacts/DummyLiquidityProvider.json';
|
||||
import * as DummyLiquidityProviderRegistry from '../generated-artifacts/DummyLiquidityProviderRegistry.json';
|
||||
import * as ERC20BridgeSampler from '../generated-artifacts/ERC20BridgeSampler.json';
|
||||
import * as ILiquidityProvider from '../generated-artifacts/ILiquidityProvider.json';
|
||||
import * as ILiquidityProviderRegistry from '../generated-artifacts/ILiquidityProviderRegistry.json';
|
||||
export const artifacts = {
|
||||
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
|
||||
ILiquidityProvider: ILiquidityProvider as ContractArtifact,
|
||||
ILiquidityProviderRegistry: ILiquidityProviderRegistry as ContractArtifact,
|
||||
DummyLiquidityProviderRegistry: DummyLiquidityProviderRegistry as ContractArtifact,
|
||||
DummyLiquidityProvider: DummyLiquidityProvider as ContractArtifact,
|
||||
};
|
||||
export const artifacts = { ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact };
|
||||
|
@@ -90,7 +90,10 @@ const DEFAULT_SWAP_QUOTE_REQUEST_OPTS: SwapQuoteRequestOpts = {
|
||||
|
||||
const DEFAULT_RFQT_REQUEST_OPTS: Partial<RfqtRequestOpts> = {
|
||||
makerEndpointMaxResponseTimeMs: 1000,
|
||||
isPriceAwareRFQEnabled: false,
|
||||
priceAwareRFQFlag: {
|
||||
isFirmPriceAwareEnabled: false,
|
||||
isIndicativePriceAwareEnabled: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_INFO_LOGGER: LogFunction = (obj, msg) =>
|
||||
|
@@ -147,10 +147,10 @@ export {
|
||||
GetMarketOrdersRfqtOpts,
|
||||
KyberFillData,
|
||||
LiquidityProviderFillData,
|
||||
LiquidityProviderRegistry,
|
||||
MarketDepth,
|
||||
MarketDepthSide,
|
||||
MooniswapFillData,
|
||||
MultiBridgeFillData,
|
||||
MultiHopFillData,
|
||||
NativeCollapsedFill,
|
||||
NativeFillData,
|
||||
|
@@ -34,7 +34,7 @@ import { getSwapMinBuyAmount } from './utils';
|
||||
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
const MAX_UINT256 = new BigNumber(2).pow(256).minus(1);
|
||||
const { NULL_ADDRESS, ZERO_AMOUNT } = constants;
|
||||
const { NULL_ADDRESS, NULL_BYTES, ZERO_AMOUNT } = constants;
|
||||
|
||||
export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
public readonly provider: ZeroExProvider;
|
||||
@@ -96,9 +96,16 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
const buyToken = getTokenFromAssetData(quote.makerAssetData);
|
||||
const sellAmount = quote.worstCaseQuoteInfo.totalTakerAssetAmount;
|
||||
let minBuyAmount = getSwapMinBuyAmount(quote);
|
||||
let ethAmount = quote.worstCaseQuoteInfo.protocolFeeInWeiAmount;
|
||||
if (isFromETH) {
|
||||
ethAmount = ethAmount.plus(sellAmount);
|
||||
}
|
||||
const { buyTokenFeeAmount, sellTokenFeeAmount, recipient: feeRecipient } = affiliateFee;
|
||||
|
||||
// VIP routes.
|
||||
if (isDirectUniswapCompatible(quote, optsWithDefaults)) {
|
||||
if (
|
||||
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap])
|
||||
) {
|
||||
const source = quote.orders[0].fills[0].source;
|
||||
const fillData = quote.orders[0].fills[0].fillData as UniswapV2FillData;
|
||||
return {
|
||||
@@ -124,6 +131,26 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
};
|
||||
}
|
||||
|
||||
if (isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.LiquidityProvider])) {
|
||||
const target = quote.orders[0].makerAddress;
|
||||
return {
|
||||
calldataHexString: this._exchangeProxy
|
||||
.sellToLiquidityProvider(
|
||||
isFromETH ? ETH_TOKEN_ADDRESS : sellToken,
|
||||
isToETH ? ETH_TOKEN_ADDRESS : buyToken,
|
||||
target,
|
||||
NULL_ADDRESS,
|
||||
sellAmount,
|
||||
minBuyAmount,
|
||||
NULL_BYTES,
|
||||
)
|
||||
.getABIEncodedTransactionData(),
|
||||
ethAmount: isFromETH ? sellAmount : ZERO_AMOUNT,
|
||||
toAddress: this._exchangeProxy.address,
|
||||
allowanceTarget: this.contractAddresses.exchangeProxyAllowanceTarget,
|
||||
};
|
||||
}
|
||||
|
||||
// Build up the transforms.
|
||||
const transforms = [];
|
||||
if (isFromETH) {
|
||||
@@ -198,8 +225,6 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
}
|
||||
|
||||
// This transformer pays affiliate fees.
|
||||
const { buyTokenFeeAmount, sellTokenFeeAmount, recipient: feeRecipient } = affiliateFee;
|
||||
|
||||
if (buyTokenFeeAmount.isGreaterThan(0) && feeRecipient !== NULL_ADDRESS) {
|
||||
transforms.push({
|
||||
deploymentNonce: this.transformerNonces.affiliateFeeTransformer,
|
||||
@@ -216,7 +241,6 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
// Adjust the minimum buy amount by the fee.
|
||||
minBuyAmount = BigNumber.max(0, minBuyAmount.minus(buyTokenFeeAmount));
|
||||
}
|
||||
|
||||
if (sellTokenFeeAmount.isGreaterThan(0) && feeRecipient !== NULL_ADDRESS) {
|
||||
throw new Error('Affiliate fees denominated in sell token are not yet supported');
|
||||
}
|
||||
@@ -240,11 +264,6 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
||||
)
|
||||
.getABIEncodedTransactionData();
|
||||
|
||||
let ethAmount = quote.worstCaseQuoteInfo.protocolFeeInWeiAmount;
|
||||
if (isFromETH) {
|
||||
ethAmount = ethAmount.plus(sellAmount);
|
||||
}
|
||||
|
||||
return {
|
||||
calldataHexString,
|
||||
ethAmount,
|
||||
@@ -266,7 +285,11 @@ function isBuyQuote(quote: SwapQuote): quote is MarketBuySwapQuote {
|
||||
return quote.type === MarketOperation.Buy;
|
||||
}
|
||||
|
||||
function isDirectUniswapCompatible(quote: SwapQuote, opts: ExchangeProxyContractOpts): boolean {
|
||||
function isDirectSwapCompatible(
|
||||
quote: SwapQuote,
|
||||
opts: ExchangeProxyContractOpts,
|
||||
directSources: ERC20BridgeSource[],
|
||||
): boolean {
|
||||
// Must not be a mtx.
|
||||
if (opts.isMetaTransaction) {
|
||||
return false;
|
||||
@@ -285,8 +308,7 @@ function isDirectUniswapCompatible(quote: SwapQuote, opts: ExchangeProxyContract
|
||||
return false;
|
||||
}
|
||||
const fill = order.fills[0];
|
||||
// And that fill must be uniswap v2 or sushiswap.
|
||||
if (![ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap].includes(fill.source)) {
|
||||
if (!directSources.includes(fill.source)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@@ -5,7 +5,7 @@ import { MarketOperation, SwapQuote } from '../types';
|
||||
import { ERC20BridgeSource } from '../utils/market_operation_utils/types';
|
||||
|
||||
/**
|
||||
* Compute the mminimum buy token amount for market operations by inferring
|
||||
* Compute the minimum buy token amount for market operations by inferring
|
||||
* the slippage from the orders in a quote. We cannot rely on
|
||||
* `worstCaseQuoteInfo.makerAssetAmount` because that does not stop at
|
||||
* maximum slippage.
|
||||
|
@@ -41,6 +41,7 @@ import { ProtocolFeeUtils } from './utils/protocol_fee_utils';
|
||||
import { QuoteRequestor } from './utils/quote_requestor';
|
||||
import { sortingUtils } from './utils/sorting_utils';
|
||||
import { SwapQuoteCalculator } from './utils/swap_quote_calculator';
|
||||
import { getPriceAwareRFQRolloutFlags } from './utils/utils';
|
||||
import { ERC20BridgeSamplerContract } from './wrappers';
|
||||
|
||||
export class SwapQuoter {
|
||||
@@ -164,8 +165,9 @@ export class SwapQuoter {
|
||||
expiryBufferMs,
|
||||
permittedOrderFeeTypes,
|
||||
samplerGasLimit,
|
||||
liquidityProviderRegistryAddress,
|
||||
rfqt,
|
||||
tokenAdjacencyGraph,
|
||||
liquidityProviderRegistry,
|
||||
} = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
|
||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||
assert.isValidOrderbook('orderbook', orderbook);
|
||||
@@ -207,13 +209,21 @@ export class SwapQuoter {
|
||||
},
|
||||
);
|
||||
this._marketOperationUtils = new MarketOperationUtils(
|
||||
new DexOrderSampler(samplerContract, samplerOverrides, provider),
|
||||
new DexOrderSampler(
|
||||
samplerContract,
|
||||
samplerOverrides,
|
||||
provider,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
tokenAdjacencyGraph,
|
||||
liquidityProviderRegistry,
|
||||
),
|
||||
this._contractAddresses,
|
||||
{
|
||||
chainId,
|
||||
exchangeAddress: this._contractAddresses.exchange,
|
||||
},
|
||||
liquidityProviderRegistryAddress,
|
||||
);
|
||||
this._swapQuoteCalculator = new SwapQuoteCalculator(this._marketOperationUtils);
|
||||
}
|
||||
@@ -700,7 +710,7 @@ export class SwapQuoter {
|
||||
|
||||
if (
|
||||
opts.rfqt && // This is an RFQT-enabled API request
|
||||
!opts.rfqt.isPriceAwareRFQEnabled && // If Price-aware RFQ is enabled, firm quotes are requested later on in the process.
|
||||
!getPriceAwareRFQRolloutFlags(opts.rfqt.priceAwareRFQFlag).isFirmPriceAwareEnabled && // If Price-aware RFQ is enabled, firm quotes are requested later on in the process.
|
||||
opts.rfqt.intentOnFilling && // The requestor is asking for a firm quote
|
||||
opts.rfqt.apiKey &&
|
||||
this._isApiKeyWhitelisted(opts.rfqt.apiKey) && // A valid API key was provided
|
||||
|
@@ -4,7 +4,13 @@ import { TakerRequestQueryParams } from '@0x/quote-server';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { ERC20BridgeSource, GetMarketOrdersOpts, OptimizedMarketOrder } from './utils/market_operation_utils/types';
|
||||
import {
|
||||
ERC20BridgeSource,
|
||||
GetMarketOrdersOpts,
|
||||
LiquidityProviderRegistry,
|
||||
OptimizedMarketOrder,
|
||||
TokenAdjacencyGraph,
|
||||
} from './utils/market_operation_utils/types';
|
||||
import { QuoteReport } from './utils/quote_report_generator';
|
||||
|
||||
/**
|
||||
@@ -234,6 +240,11 @@ export type SwapQuoteOrdersBreakdown = Partial<
|
||||
}
|
||||
>;
|
||||
|
||||
export interface PriceAwareRFQFlags {
|
||||
isIndicativePriceAwareEnabled: boolean;
|
||||
isFirmPriceAwareEnabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* nativeExclusivelyRFQT: if set to `true`, Swap quote will exclude Open Orderbook liquidity.
|
||||
* If set to `true` and `ERC20BridgeSource.Native` is part of the `excludedSources`
|
||||
@@ -256,7 +267,7 @@ export interface RfqtRequestOpts {
|
||||
* the feature flag. When that time comes, follow this PR to "undo" the feature flag:
|
||||
* https://github.com/0xProject/0x-monorepo/pull/2735
|
||||
*/
|
||||
isPriceAwareRFQEnabled?: boolean;
|
||||
priceAwareRFQFlag?: PriceAwareRFQFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,11 +316,12 @@ export interface SwapQuoterOpts extends OrderPrunerOpts {
|
||||
ethereumRpcUrl?: string;
|
||||
contractAddresses?: AssetSwapperContractAddresses;
|
||||
samplerGasLimit?: number;
|
||||
liquidityProviderRegistryAddress?: string;
|
||||
multiBridgeAddress?: string;
|
||||
ethGasStationUrl?: string;
|
||||
rfqt?: SwapQuoterRfqtOpts;
|
||||
samplerOverrides?: SamplerOverrides;
|
||||
tokenAdjacencyGraph?: TokenAdjacencyGraph;
|
||||
liquidityProviderRegistry?: LiquidityProviderRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -13,6 +13,7 @@ import {
|
||||
FeeSchedule,
|
||||
FillData,
|
||||
GetMarketOrdersOpts,
|
||||
LiquidityProviderRegistry,
|
||||
MultiHopFillData,
|
||||
SnowSwapFillData,
|
||||
SushiSwapFillData,
|
||||
@@ -24,55 +25,51 @@ import {
|
||||
/**
|
||||
* Valid sources for market sell.
|
||||
*/
|
||||
export const SELL_SOURCE_FILTER = new SourceFilters(
|
||||
[
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
// Bancor is sampled off-chain, but this list should only include on-chain sources (used in ERC20BridgeSampler)
|
||||
// ERC20BridgeSource.Bancor,
|
||||
ERC20BridgeSource.MStable,
|
||||
ERC20BridgeSource.Mooniswap,
|
||||
ERC20BridgeSource.Swerve,
|
||||
ERC20BridgeSource.SnowSwap,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
],
|
||||
[ERC20BridgeSource.MultiBridge],
|
||||
);
|
||||
export const SELL_SOURCE_FILTER = new SourceFilters([
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
// Bancor is sampled off-chain, but this list should only include on-chain sources (used in ERC20BridgeSampler)
|
||||
// ERC20BridgeSource.Bancor,
|
||||
ERC20BridgeSource.MStable,
|
||||
ERC20BridgeSource.Mooniswap,
|
||||
ERC20BridgeSource.Swerve,
|
||||
ERC20BridgeSource.SnowSwap,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
ERC20BridgeSource.LiquidityProvider,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Valid sources for market buy.
|
||||
*/
|
||||
export const BUY_SOURCE_FILTER = new SourceFilters(
|
||||
[
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
// ERC20BridgeSource.Bancor, // FIXME: Disabled until Bancor SDK supports buy quotes
|
||||
ERC20BridgeSource.MStable,
|
||||
ERC20BridgeSource.Mooniswap,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.Swerve,
|
||||
ERC20BridgeSource.SnowSwap,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
],
|
||||
[ERC20BridgeSource.MultiBridge],
|
||||
);
|
||||
export const BUY_SOURCE_FILTER = new SourceFilters([
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
// ERC20BridgeSource.Bancor, // FIXME: Disabled until Bancor SDK supports buy quotes
|
||||
ERC20BridgeSource.MStable,
|
||||
ERC20BridgeSource.Mooniswap,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.Swerve,
|
||||
ERC20BridgeSource.SnowSwap,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
ERC20BridgeSource.LiquidityProvider,
|
||||
]);
|
||||
|
||||
/**
|
||||
* 0x Protocol Fee Multiplier
|
||||
@@ -98,29 +95,60 @@ export const TOKENS = {
|
||||
USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
sUSD: '0x57ab1ec28d129707052df4df418d58a2d46d5f51',
|
||||
BUSD: '0x4fabb145d64652a948d72533023f6e7a623c7c53',
|
||||
TUSD: '0x0000000000085d4780b73119b644ae5ecd22b376',
|
||||
PAX: '0x8e870d67f660d95d5be530380d0ec0bd388289e1',
|
||||
GUSD: '0x056fd409e1d7a124bd7017459dfea2f387b6d5cd',
|
||||
HUSD: '0xdf574c24545e5ffecb9a659c229253d4111d87e1',
|
||||
mUSD: '0xe2f2a5c287993345a840db3b0845fbc70f5935a5',
|
||||
USDN: '0x674c6ad92fd080e4004b2312b45f796a192d27a0',
|
||||
// Bitcoins
|
||||
WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
|
||||
RenBTC: '0xeb4c2781e4eba804ce9a9803c67d0893436bb27d',
|
||||
sBTC: '0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6',
|
||||
tBTC: '0x8daebade922df735c38c80c7ebd708af50815faa',
|
||||
hBTC: '0x0316eb71485b0ab14103307bf65a021042c6d380',
|
||||
// Other
|
||||
MKR: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
|
||||
};
|
||||
|
||||
export const POOLS = {
|
||||
// following the same order in curve.fi:
|
||||
curve_compound: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56',
|
||||
// curve_USDT: '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c',
|
||||
curve_PAX: '0x06364f10b501e868329afbc005b3492902d6c763',
|
||||
curve_y: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51',
|
||||
curve_BUSD: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27',
|
||||
curve_sUSD: '0xa5407eae9ba41422680e2e00537571bcc53efbfd',
|
||||
curve_renBTC: '0x93054188d876f558f4a66b2ef1d97d16edf0895b',
|
||||
curve_sBTC: '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714',
|
||||
curve_HBTC: '0x4ca9b3063ec5866a4b82e437059d2c43d1be596f',
|
||||
curve_TRI: '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7',
|
||||
curve_GUSD: '0x4f062658eaaf2c1ccf8c8e36d6824cdf41167956',
|
||||
curve_HUSD: '0x3ef6a01a0f81d6046290f3e2a8c5b843e738e604',
|
||||
// 12.usdk is dead
|
||||
curve_USDN: '0x0f9cb53ebe405d49a0bbdbd291a65ff571bc83e1',
|
||||
// 14.linkusd is dead
|
||||
curve_mUSD: '0x8474ddbe98f5aa3179b3b3f5942d724afcdec9f6',
|
||||
// 16.rsv is dead
|
||||
curve_tBTC: '0xc25099792e9349c7dd09759744ea681c7de2cb66',
|
||||
};
|
||||
|
||||
/**
|
||||
* Mainnet Curve configuration
|
||||
* The tokens are in order of their index, which each curve defines
|
||||
* I.e DaiUsdc curve has DAI as index 0 and USDC as index 1
|
||||
*/
|
||||
export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
DaiUsdc: {
|
||||
[POOLS.curve_compound]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
poolAddress: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56',
|
||||
poolAddress: POOLS.curve_compound,
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC],
|
||||
metaToken: undefined,
|
||||
},
|
||||
// DaiUsdcUsdt: {
|
||||
// USDT: {
|
||||
// exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
// sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
// buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
@@ -131,53 +159,110 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
// TOKENS.USDT,
|
||||
// ],
|
||||
// },
|
||||
DaiUsdcUsdtTusd: {
|
||||
[POOLS.curve_PAX]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_PAX,
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.PAX],
|
||||
metaToken: undefined,
|
||||
},
|
||||
[POOLS.curve_y]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
poolAddress: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51',
|
||||
poolAddress: POOLS.curve_y,
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.TUSD],
|
||||
metaToken: undefined,
|
||||
},
|
||||
// Looks like it's dying.
|
||||
DaiUsdcUsdtBusd: {
|
||||
[POOLS.curve_BUSD]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
poolAddress: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27',
|
||||
tokens: [
|
||||
TOKENS.DAI,
|
||||
TOKENS.USDC,
|
||||
TOKENS.USDT,
|
||||
'0x4fabb145d64652a948d72533023f6e7a623c7c53', // bUSD
|
||||
],
|
||||
poolAddress: POOLS.curve_BUSD,
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.BUSD],
|
||||
metaToken: undefined,
|
||||
},
|
||||
DaiUsdcUsdtSusd: {
|
||||
[POOLS.curve_sUSD]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0xa5407eae9ba41422680e2e00537571bcc53efbfd',
|
||||
poolAddress: POOLS.curve_sUSD,
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.sUSD],
|
||||
metaToken: undefined,
|
||||
},
|
||||
RenbtcWbtc: {
|
||||
[POOLS.curve_renBTC]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0x93054188d876f558f4a66b2ef1d97d16edf0895b',
|
||||
poolAddress: POOLS.curve_renBTC,
|
||||
tokens: [TOKENS.RenBTC, TOKENS.WBTC],
|
||||
metaToken: undefined,
|
||||
},
|
||||
RenbtcWbtcSbtc: {
|
||||
[POOLS.curve_sBTC]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714',
|
||||
poolAddress: POOLS.curve_sBTC,
|
||||
tokens: [TOKENS.RenBTC, TOKENS.WBTC, TOKENS.sBTC],
|
||||
metaToken: undefined,
|
||||
},
|
||||
TriPool: {
|
||||
[POOLS.curve_HBTC]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7',
|
||||
poolAddress: POOLS.curve_HBTC,
|
||||
tokens: [TOKENS.hBTC, TOKENS.WBTC],
|
||||
metaToken: undefined,
|
||||
},
|
||||
[POOLS.curve_TRI]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_TRI,
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT],
|
||||
metaToken: undefined,
|
||||
},
|
||||
// Metapools
|
||||
[POOLS.curve_GUSD]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_GUSD,
|
||||
tokens: [TOKENS.GUSD, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT],
|
||||
metaToken: TOKENS.GUSD,
|
||||
},
|
||||
[POOLS.curve_HUSD]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_HUSD,
|
||||
tokens: [TOKENS.HUSD, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT],
|
||||
metaToken: TOKENS.HUSD,
|
||||
},
|
||||
[POOLS.curve_USDN]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_USDN,
|
||||
tokens: [TOKENS.USDN, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT],
|
||||
metaToken: TOKENS.USDN,
|
||||
},
|
||||
[POOLS.curve_mUSD]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_mUSD,
|
||||
tokens: [TOKENS.mUSD, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT],
|
||||
metaToken: TOKENS.mUSD,
|
||||
},
|
||||
[POOLS.curve_tBTC]: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: POOLS.curve_tBTC,
|
||||
tokens: [TOKENS.tBTC, TOKENS.RenBTC, TOKENS.WBTC, TOKENS.sBTC],
|
||||
metaToken: TOKENS.tBTC,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -188,6 +273,7 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', // _target: 0xa5407eae9ba41422680e2e00537571bcc53efbfd
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.TUSD],
|
||||
metaToken: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -201,6 +287,7 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = {
|
||||
'0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD
|
||||
'0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV
|
||||
],
|
||||
metaToken: undefined,
|
||||
},
|
||||
yVaultCurveUnderlying: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
@@ -211,6 +298,7 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = {
|
||||
'0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8', // yCRV
|
||||
'0x3b3ac5386837dc563660fb6a0937dfaa5924333b', // bCRV
|
||||
],
|
||||
metaToken: undefined,
|
||||
},
|
||||
yVaultUSD: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
@@ -223,20 +311,8 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = {
|
||||
'0x2f08119c6f07c006695e079aafc638b8789faf18', // yUSDT
|
||||
'0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD
|
||||
],
|
||||
metaToken: undefined,
|
||||
},
|
||||
// Gas is too high for these underlying tokens (3M+)
|
||||
// yVaultUSDUnderlying: {
|
||||
// exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
// sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
// buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
// poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b',
|
||||
// tokens: [
|
||||
// TOKENS.DAI,
|
||||
// TOKENS.USDC,
|
||||
// TOKENS.USDT,
|
||||
// TOKENS.TUSD,
|
||||
// ],
|
||||
// },
|
||||
};
|
||||
|
||||
export const MAINNET_KYBER_RESERVE_IDS: { [name: string]: string } = {
|
||||
@@ -273,6 +349,8 @@ export const MAINNET_KYBER_TOKEN_RESERVE_IDS: { [token: string]: string } = {
|
||||
'0xaa42414e44000000000000000000000000000000000000000000000000000000',
|
||||
};
|
||||
|
||||
export const LIQUIDITY_PROVIDER_REGISTRY: LiquidityProviderRegistry = {};
|
||||
|
||||
export const MAINNET_SUSHI_SWAP_ROUTER = '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F';
|
||||
|
||||
export const MAINNET_SHELL_POOLS = {
|
||||
@@ -361,19 +439,25 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
|
||||
[ERC20BridgeSource.Curve]: fillData => {
|
||||
const poolAddress = (fillData as CurveFillData).pool.poolAddress.toLowerCase();
|
||||
switch (poolAddress) {
|
||||
case '0xa5407eae9ba41422680e2e00537571bcc53efbfd':
|
||||
case '0x93054188d876f558f4a66b2ef1d97d16edf0895b':
|
||||
case '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714':
|
||||
case '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7':
|
||||
case POOLS.curve_renBTC:
|
||||
case POOLS.curve_sBTC:
|
||||
case POOLS.curve_sUSD:
|
||||
case POOLS.curve_HBTC:
|
||||
case POOLS.curve_TRI:
|
||||
return 150e3;
|
||||
case '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56':
|
||||
case POOLS.curve_compound:
|
||||
return 750e3;
|
||||
case '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51':
|
||||
case POOLS.curve_PAX:
|
||||
case POOLS.curve_y:
|
||||
case POOLS.curve_BUSD:
|
||||
return 850e3;
|
||||
case '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27':
|
||||
return 1e6;
|
||||
case '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c':
|
||||
return 600e3;
|
||||
// Metapools
|
||||
case POOLS.curve_GUSD:
|
||||
case POOLS.curve_HUSD:
|
||||
case POOLS.curve_USDN:
|
||||
case POOLS.curve_mUSD:
|
||||
case POOLS.curve_tBTC:
|
||||
return 650e3;
|
||||
default:
|
||||
throw new Error(`Unrecognized Curve address: ${poolAddress}`);
|
||||
}
|
||||
@@ -459,5 +543,5 @@ export const DEFAULT_GET_MARKET_ORDERS_OPTS: GetMarketOrdersOpts = {
|
||||
exchangeProxyOverhead: () => ZERO_AMOUNT,
|
||||
allowFallback: true,
|
||||
shouldGenerateQuoteReport: false,
|
||||
tokenAdjacencyGraph: {},
|
||||
tokenAdjacencyGraph: { default: [] },
|
||||
};
|
||||
|
@@ -3,13 +3,31 @@ import { CurveInfo, SnowSwapInfo, SwerveInfo } from './types';
|
||||
|
||||
// tslint:disable completed-docs
|
||||
export function getCurveInfosForPair(takerToken: string, makerToken: string): CurveInfo[] {
|
||||
return Object.values(MAINNET_CURVE_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)));
|
||||
return Object.values(MAINNET_CURVE_INFOS).filter(c =>
|
||||
[makerToken, takerToken].every(
|
||||
t =>
|
||||
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function getSwerveInfosForPair(takerToken: string, makerToken: string): SwerveInfo[] {
|
||||
return Object.values(MAINNET_SWERVE_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)));
|
||||
return Object.values(MAINNET_SWERVE_INFOS).filter(c =>
|
||||
[makerToken, takerToken].every(
|
||||
t =>
|
||||
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function getSnowSwapInfosForPair(takerToken: string, makerToken: string): SnowSwapInfo[] {
|
||||
return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)));
|
||||
return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c =>
|
||||
[makerToken, takerToken].every(
|
||||
t =>
|
||||
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import * as _ from 'lodash';
|
||||
|
||||
import { AssetSwapperContractAddresses, MarketOperation, Omit } from '../../types';
|
||||
import { QuoteRequestor } from '../quote_requestor';
|
||||
import { getPriceAwareRFQRolloutFlags } from '../utils';
|
||||
|
||||
import { generateQuoteReport, QuoteReport } from './../quote_report_generator';
|
||||
import {
|
||||
@@ -77,7 +78,6 @@ export async function getRfqtIndicativeQuotesAsync(
|
||||
|
||||
export class MarketOperationUtils {
|
||||
private readonly _wethAddress: string;
|
||||
private readonly _multiBridge: string;
|
||||
private readonly _sellSources: SourceFilters;
|
||||
private readonly _buySources: SourceFilters;
|
||||
private readonly _feeSources = new SourceFilters(FEE_QUOTE_SOURCES);
|
||||
@@ -107,19 +107,10 @@ export class MarketOperationUtils {
|
||||
private readonly _sampler: DexOrderSampler,
|
||||
private readonly contractAddresses: AssetSwapperContractAddresses,
|
||||
private readonly _orderDomain: OrderDomain,
|
||||
private readonly _liquidityProviderRegistry: string = NULL_ADDRESS,
|
||||
) {
|
||||
this._wethAddress = contractAddresses.etherToken.toLowerCase();
|
||||
this._multiBridge = contractAddresses.multiBridge.toLowerCase();
|
||||
const optionalQuoteSources = [];
|
||||
if (this._liquidityProviderRegistry !== NULL_ADDRESS) {
|
||||
optionalQuoteSources.push(ERC20BridgeSource.LiquidityProvider);
|
||||
}
|
||||
if (this._multiBridge !== NULL_ADDRESS) {
|
||||
optionalQuoteSources.push(ERC20BridgeSource.MultiBridge);
|
||||
}
|
||||
this._buySources = BUY_SOURCE_FILTER.validate(optionalQuoteSources);
|
||||
this._sellSources = SELL_SOURCE_FILTER.validate(optionalQuoteSources);
|
||||
this._buySources = BUY_SOURCE_FILTER;
|
||||
this._sellSources = SELL_SOURCE_FILTER;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,46 +166,26 @@ export class MarketOperationUtils {
|
||||
// Get native order fillable amounts.
|
||||
this._sampler.getOrderFillableTakerAmounts(nativeOrders, this.contractAddresses.exchange),
|
||||
// Get ETH -> maker token price.
|
||||
this._sampler.getMedianSellRate(
|
||||
feeSourceFilters.sources,
|
||||
makerToken,
|
||||
this._wethAddress,
|
||||
ONE_ETHER,
|
||||
this._liquidityProviderRegistry,
|
||||
this._multiBridge,
|
||||
),
|
||||
this._sampler.getMedianSellRate(feeSourceFilters.sources, makerToken, this._wethAddress, ONE_ETHER),
|
||||
// Get ETH -> taker token price.
|
||||
this._sampler.getMedianSellRate(
|
||||
feeSourceFilters.sources,
|
||||
takerToken,
|
||||
this._wethAddress,
|
||||
ONE_ETHER,
|
||||
this._liquidityProviderRegistry,
|
||||
this._multiBridge,
|
||||
),
|
||||
this._sampler.getMedianSellRate(feeSourceFilters.sources, takerToken, this._wethAddress, ONE_ETHER),
|
||||
// Get sell quotes for taker -> maker.
|
||||
this._sampler.getSellQuotes(
|
||||
quoteSourceFilters.exclude(offChainSources).sources,
|
||||
makerToken,
|
||||
takerToken,
|
||||
sampleAmounts,
|
||||
this._wethAddress,
|
||||
_opts.tokenAdjacencyGraph,
|
||||
this._liquidityProviderRegistry,
|
||||
this._multiBridge,
|
||||
),
|
||||
this._sampler.getTwoHopSellQuotes(
|
||||
quoteSourceFilters.isAllowed(ERC20BridgeSource.MultiHop) ? quoteSourceFilters.sources : [],
|
||||
makerToken,
|
||||
takerToken,
|
||||
takerAmount,
|
||||
this._wethAddress,
|
||||
_opts.tokenAdjacencyGraph,
|
||||
this._liquidityProviderRegistry,
|
||||
),
|
||||
);
|
||||
|
||||
const isPriceAwareRfqEnabled = _opts.rfqt && _opts.rfqt.isPriceAwareRFQEnabled;
|
||||
const isPriceAwareRfqEnabled =
|
||||
_opts.rfqt && getPriceAwareRFQRolloutFlags(_opts.rfqt.priceAwareRFQFlag).isIndicativePriceAwareEnabled;
|
||||
const rfqtPromise =
|
||||
!isPriceAwareRfqEnabled && quoteSourceFilters.isAllowed(ERC20BridgeSource.Native)
|
||||
? getRfqtIndicativeQuotesAsync(
|
||||
@@ -325,44 +296,25 @@ export class MarketOperationUtils {
|
||||
// Get native order fillable amounts.
|
||||
this._sampler.getOrderFillableMakerAmounts(nativeOrders, this.contractAddresses.exchange),
|
||||
// Get ETH -> makerToken token price.
|
||||
this._sampler.getMedianSellRate(
|
||||
feeSourceFilters.sources,
|
||||
makerToken,
|
||||
this._wethAddress,
|
||||
ONE_ETHER,
|
||||
this._liquidityProviderRegistry,
|
||||
this._multiBridge,
|
||||
),
|
||||
this._sampler.getMedianSellRate(feeSourceFilters.sources, makerToken, this._wethAddress, ONE_ETHER),
|
||||
// Get ETH -> taker token price.
|
||||
this._sampler.getMedianSellRate(
|
||||
feeSourceFilters.sources,
|
||||
takerToken,
|
||||
this._wethAddress,
|
||||
ONE_ETHER,
|
||||
this._liquidityProviderRegistry,
|
||||
this._multiBridge,
|
||||
),
|
||||
this._sampler.getMedianSellRate(feeSourceFilters.sources, takerToken, this._wethAddress, ONE_ETHER),
|
||||
// Get buy quotes for taker -> maker.
|
||||
this._sampler.getBuyQuotes(
|
||||
quoteSourceFilters.exclude(offChainSources).sources,
|
||||
makerToken,
|
||||
takerToken,
|
||||
sampleAmounts,
|
||||
this._wethAddress,
|
||||
_opts.tokenAdjacencyGraph,
|
||||
this._liquidityProviderRegistry,
|
||||
),
|
||||
this._sampler.getTwoHopBuyQuotes(
|
||||
quoteSourceFilters.isAllowed(ERC20BridgeSource.MultiHop) ? quoteSourceFilters.sources : [],
|
||||
makerToken,
|
||||
takerToken,
|
||||
makerAmount,
|
||||
this._wethAddress,
|
||||
_opts.tokenAdjacencyGraph,
|
||||
this._liquidityProviderRegistry,
|
||||
),
|
||||
);
|
||||
const isPriceAwareRfqEnabled = _opts.rfqt && _opts.rfqt.isPriceAwareRFQEnabled;
|
||||
const isPriceAwareRfqEnabled =
|
||||
_opts.rfqt && getPriceAwareRFQRolloutFlags(_opts.rfqt.priceAwareRFQFlag).isIndicativePriceAwareEnabled;
|
||||
const rfqtPromise =
|
||||
!isPriceAwareRfqEnabled && quoteSourceFilters.isAllowed(ERC20BridgeSource.Native)
|
||||
? getRfqtIndicativeQuotesAsync(
|
||||
@@ -388,10 +340,6 @@ export class MarketOperationUtils {
|
||||
offChainBalancerQuotes,
|
||||
offChainCreamQuotes,
|
||||
] = await Promise.all([samplerPromise, rfqtPromise, offChainBalancerPromise, offChainCreamPromise]);
|
||||
// Attach the MultiBridge address to the sample fillData
|
||||
(dexQuotes.find(quotes => quotes[0] && quotes[0].source === ERC20BridgeSource.MultiBridge) || []).forEach(
|
||||
q => (q.fillData = { poolAddress: this._multiBridge }),
|
||||
);
|
||||
const [makerTokenDecimals, takerTokenDecimals] = tokenDecimals;
|
||||
return {
|
||||
side: MarketOperation.Buy,
|
||||
@@ -479,7 +427,6 @@ export class MarketOperationUtils {
|
||||
getNativeOrderTokens(orders[0])[1],
|
||||
this._wethAddress,
|
||||
ONE_ETHER,
|
||||
this._wethAddress,
|
||||
),
|
||||
),
|
||||
...batchNativeOrders.map((orders, i) =>
|
||||
@@ -488,8 +435,6 @@ export class MarketOperationUtils {
|
||||
getNativeOrderTokens(orders[0])[0],
|
||||
getNativeOrderTokens(orders[0])[1],
|
||||
[makerAmounts[i]],
|
||||
this._wethAddress,
|
||||
_opts.tokenAdjacencyGraph,
|
||||
),
|
||||
),
|
||||
];
|
||||
@@ -677,12 +622,7 @@ export class MarketOperationUtils {
|
||||
// If RFQ liquidity is enabled, make a request to check RFQ liquidity
|
||||
let comparisonPrice: BigNumber | undefined;
|
||||
const { rfqt } = _opts;
|
||||
if (
|
||||
rfqt &&
|
||||
rfqt.isPriceAwareRFQEnabled &&
|
||||
rfqt.quoteRequestor &&
|
||||
marketSideLiquidity.quoteSourceFilters.isAllowed(ERC20BridgeSource.Native)
|
||||
) {
|
||||
if (rfqt && rfqt.quoteRequestor && marketSideLiquidity.quoteSourceFilters.isAllowed(ERC20BridgeSource.Native)) {
|
||||
// Calculate a suggested price. For now, this is simply the overall price of the aggregation.
|
||||
if (optimizerResult) {
|
||||
const totalMakerAmount = BigNumber.sum(
|
||||
@@ -706,8 +646,12 @@ export class MarketOperationUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// If we are making an indicative quote, make the RFQT request and then re-run the sampler if new orders come back.
|
||||
if (rfqt.isIndicative) {
|
||||
const { isFirmPriceAwareEnabled, isIndicativePriceAwareEnabled } = getPriceAwareRFQRolloutFlags(
|
||||
rfqt.priceAwareRFQFlag,
|
||||
);
|
||||
|
||||
if (rfqt.isIndicative && isIndicativePriceAwareEnabled) {
|
||||
// An indicative quote is beingh requested, and indicative quotes price-aware enabled. Make the RFQT request and then re-run the sampler if new orders come back.
|
||||
const indicativeQuotes = await getRfqtIndicativeQuotesAsync(
|
||||
nativeOrders[0].makerAssetData,
|
||||
nativeOrders[0].takerAssetData,
|
||||
@@ -726,8 +670,8 @@ export class MarketOperationUtils {
|
||||
optimizerOpts,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// A firm quote is being requested. Ensure that `intentOnFilling` is enabled.
|
||||
} else if (!rfqt.isIndicative && isFirmPriceAwareEnabled) {
|
||||
// A firm quote is being requested, and firm quotes price-aware enabled. Ensure that `intentOnFilling` is enabled.
|
||||
if (rfqt.intentOnFilling) {
|
||||
// Extra validation happens when requesting a firm quote, such as ensuring that the takerAddress
|
||||
// is indeed valid.
|
||||
|
@@ -0,0 +1,12 @@
|
||||
import { LiquidityProviderRegistry } from './types';
|
||||
|
||||
// tslint:disable completed-docs
|
||||
export function getLiquidityProvidersForPair(
|
||||
registry: LiquidityProviderRegistry,
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
): string[] {
|
||||
return Object.entries(registry)
|
||||
.filter(([, tokens]) => [makerToken, takerToken].every(t => tokens.includes(t)))
|
||||
.map(([providerAddress]) => providerAddress);
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
import { NULL_ADDRESS, TOKENS } from './constants';
|
||||
|
||||
// tslint:disable completed-docs
|
||||
|
||||
export function getMultiBridgeIntermediateToken(takerToken: string, makerToken: string): string {
|
||||
let intermediateToken = NULL_ADDRESS;
|
||||
if (takerToken !== TOKENS.WETH && makerToken !== TOKENS.WETH) {
|
||||
intermediateToken = TOKENS.WETH;
|
||||
} else if (takerToken === TOKENS.USDC || makerToken === TOKENS.USDC) {
|
||||
intermediateToken = TOKENS.DAI;
|
||||
}
|
||||
return intermediateToken;
|
||||
}
|
@@ -21,19 +21,11 @@ export function getIntermediateTokens(
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
tokenAdjacencyGraph: TokenAdjacencyGraph,
|
||||
wethAddress: string,
|
||||
): string[] {
|
||||
let intermediateTokens = [];
|
||||
if (makerToken === wethAddress) {
|
||||
intermediateTokens = _.get(tokenAdjacencyGraph, takerToken, [] as string[]);
|
||||
} else if (takerToken === wethAddress) {
|
||||
intermediateTokens = _.get(tokenAdjacencyGraph, makerToken, [] as string[]);
|
||||
} else {
|
||||
intermediateTokens = _.union(
|
||||
_.intersection(_.get(tokenAdjacencyGraph, takerToken, []), _.get(tokenAdjacencyGraph, makerToken, [])),
|
||||
[wethAddress],
|
||||
);
|
||||
}
|
||||
const intermediateTokens = _.intersection(
|
||||
_.get(tokenAdjacencyGraph, takerToken, tokenAdjacencyGraph.default),
|
||||
_.get(tokenAdjacencyGraph, makerToken, tokenAdjacencyGraph.default),
|
||||
);
|
||||
return _.uniqBy(intermediateTokens, a => a.toLowerCase()).filter(
|
||||
token => token.toLowerCase() !== makerToken.toLowerCase() && token.toLowerCase() !== takerToken.toLowerCase(),
|
||||
);
|
||||
|
@@ -15,7 +15,6 @@ import {
|
||||
WALLET_SIGNATURE,
|
||||
ZERO_AMOUNT,
|
||||
} from './constants';
|
||||
import { getMultiBridgeIntermediateToken } from './multibridge_utils';
|
||||
import {
|
||||
AggregationError,
|
||||
BalancerFillData,
|
||||
@@ -28,7 +27,6 @@ import {
|
||||
KyberFillData,
|
||||
LiquidityProviderFillData,
|
||||
MooniswapFillData,
|
||||
MultiBridgeFillData,
|
||||
MultiHopFillData,
|
||||
NativeCollapsedFill,
|
||||
OptimizedMarketOrder,
|
||||
@@ -193,8 +191,6 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath
|
||||
return opts.contractAddresses.creamBridge;
|
||||
case ERC20BridgeSource.LiquidityProvider:
|
||||
return (fill.fillData as LiquidityProviderFillData).poolAddress;
|
||||
case ERC20BridgeSource.MultiBridge:
|
||||
return (fill.fillData as MultiBridgeFillData).poolAddress;
|
||||
case ERC20BridgeSource.MStable:
|
||||
return opts.contractAddresses.mStableBridge;
|
||||
case ERC20BridgeSource.Mooniswap:
|
||||
@@ -301,13 +297,6 @@ export function createBridgeOrder(
|
||||
createSushiSwapBridgeData(sushiSwapFillData.tokenAddressPath, sushiSwapFillData.router),
|
||||
);
|
||||
break;
|
||||
case ERC20BridgeSource.MultiBridge:
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
makerToken,
|
||||
bridgeAddress,
|
||||
createMultiBridgeData(takerToken, makerToken),
|
||||
);
|
||||
break;
|
||||
case ERC20BridgeSource.Kyber:
|
||||
const kyberFillData = (fill as CollapsedFill<KyberFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
@@ -372,15 +361,6 @@ function createBridgeData(tokenAddress: string): string {
|
||||
return encoder.encode({ tokenAddress });
|
||||
}
|
||||
|
||||
function createMultiBridgeData(takerToken: string, makerToken: string): string {
|
||||
const intermediateToken = getMultiBridgeIntermediateToken(takerToken, makerToken);
|
||||
const encoder = AbiEncoder.create([
|
||||
{ name: 'takerToken', type: 'address' },
|
||||
{ name: 'intermediateToken', type: 'address' },
|
||||
]);
|
||||
return encoder.encode({ takerToken, intermediateToken });
|
||||
}
|
||||
|
||||
function createBalancerBridgeData(takerToken: string, poolAddress: string): string {
|
||||
const encoder = AbiEncoder.create([
|
||||
{ name: 'takerToken', type: 'address' },
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user