Compare commits
42 Commits
@0x/contra
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
ccf2000c09 | ||
|
3eb2e0f56a | ||
|
d07c7d5b69 | ||
|
adf6684c29 | ||
|
9bf889aa30 | ||
|
e81c88564e | ||
|
901d400d62 | ||
|
289474e2ce | ||
|
407ca21168 | ||
|
5c68fc24d2 | ||
|
548800e0a9 | ||
|
bde3d6dc6a | ||
|
56550a6acc | ||
|
e51b83accc | ||
|
d5ae971f1c | ||
|
5a2f5f9a42 | ||
|
75a3b70cef | ||
|
803cf65ba1 | ||
|
5d3947b838 | ||
|
4397a59008 | ||
|
966d54c935 | ||
|
234ddb495d | ||
|
a744acc7bc | ||
|
27c624633c | ||
|
7ef75101b4 | ||
|
6f8aace00d | ||
|
6c264b2f18 | ||
|
df055e1958 | ||
|
70d2117470 | ||
|
2c173ccaf3 | ||
|
d2f4a0c5f3 | ||
|
0d6021e5e3 | ||
|
bb04726e7f | ||
|
220ca370c2 | ||
|
63af4e3e98 | ||
|
9754e12d82 | ||
|
d72ebed246 | ||
|
587fc71058 | ||
|
7d34e09a12 | ||
|
7d15baad0f | ||
|
1e6476ada7 | ||
|
1d6ca5f6b5 |
@@ -2,11 +2,11 @@ version: 2.1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
resource_class: large
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
- image: node:12
|
||||
environment:
|
||||
NODE_OPTIONS: '--max-old-space-size=6442'
|
||||
NODE_OPTIONS: '--max-old-space-size=16384'
|
||||
working_directory: ~/repo
|
||||
steps:
|
||||
- checkout
|
||||
@@ -18,8 +18,8 @@ jobs:
|
||||
name: yarn
|
||||
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
|
||||
- setup_remote_docker
|
||||
- run: yarn build:ci || yarn build:ci || yarn build:ci
|
||||
- run: yarn build:ts || yarn build:ts || yarn build:ts
|
||||
- run: yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci || yarn build:ci
|
||||
- run: yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts || yarn build:ts
|
||||
- save_cache:
|
||||
key: repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
|
@@ -3,5 +3,6 @@
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
@@ -49,7 +49,6 @@
|
||||
| Package | Version |
|
||||
| ------: | :------ |
|
||||
|
||||
|
||||
<!-- For example:
|
||||
| `0x.js` | 2.0.4 |
|
||||
| `Exchange Contract` | v2 |
|
||||
|
@@ -43,12 +43,12 @@ These packages are all under development. See [/contracts/README.md](/contracts/
|
||||
#### 0x-specific packages
|
||||
|
||||
| Package | Version | Description |
|
||||
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | A tiny utility library for getting known deployed contract addresses for a particular network. |
|
||||
| [`@0x/contract-wrappers`](/packages/contract-wrappers) | [](https://www.npmjs.com/package/@0x/contract-wrappers) | JS/TS wrappers for interacting with the 0x smart contracts |
|
||||
| [`@0x/order-utils`](/packages/order-utils) | [](https://www.npmjs.com/package/@0x/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders |
|
||||
| [`@0x/migrations`](/packages/migrations) | [](https://www.npmjs.com/package/@0x/migrations) | Migration tool for deploying 0x smart contracts on private testnets |
|
||||
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts | |
|
||||
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts | |
|
||||
|
||||
## Usage
|
||||
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "3.7.15",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "3.7.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "3.7.13",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "3.7.12",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "3.7.11",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.7.15 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.7.14 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.7.13 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.7.12 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.7.11 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-asset-proxy",
|
||||
"version": "3.7.11",
|
||||
"version": "3.7.15",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,10 +52,10 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contract-wrappers": "^13.16.1",
|
||||
"@0x/contract-wrappers": "^13.17.1",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -80,11 +80,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-erc1155": "^2.1.29",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-erc721": "^3.1.29",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/contracts-erc1155": "^2.1.33",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-erc721": "^3.1.33",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/types": "^3.3.3",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
"@0x/utils": "^6.4.3",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "1.1.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "1.1.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "1.1.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "1.1.30",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "1.1.29",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.33 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.32 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.31 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.30 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.29 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-broker",
|
||||
"version": "1.1.29",
|
||||
"version": "1.1.33",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,14 +52,14 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-erc721": "^3.1.29",
|
||||
"@0x/contracts-exchange": "^3.2.30",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-erc721": "^3.1.33",
|
||||
"@0x/contracts-exchange": "^3.2.34",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
@@ -85,7 +85,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
"@0x/utils": "^6.4.3",
|
||||
"ethereum-types": "^3.5.0"
|
||||
|
@@ -7,7 +7,10 @@ export interface GodsUnchainedProperties {
|
||||
quality: BigNumber | number;
|
||||
}
|
||||
|
||||
const propertyDataEncoder = AbiEncoder.create([{ name: 'proto', type: 'uint16' }, { name: 'quality', type: 'uint8' }]);
|
||||
const propertyDataEncoder = AbiEncoder.create([
|
||||
{ name: 'proto', type: 'uint16' },
|
||||
{ name: 'quality', type: 'uint8' },
|
||||
]);
|
||||
const brokerDataEncoder = AbiEncoder.create([
|
||||
{ name: 'godsUnchainedAddress', type: 'address' },
|
||||
{ name: 'validatorAddress', type: 'address' },
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "3.1.34",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "3.1.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "3.1.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "3.1.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "3.1.30",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.34 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.33 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.32 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.31 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.30 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-coordinator",
|
||||
"version": "3.1.30",
|
||||
"version": "3.1.34",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,12 +53,12 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-dev-utils": "^1.3.28",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-dev-utils": "^1.3.32",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
@@ -84,10 +84,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.27",
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contract-addresses": "^6.1.0",
|
||||
"@0x/contracts-exchange": "^3.2.30",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contract-addresses": "^6.3.1",
|
||||
"@0x/contracts-exchange": "^3.2.34",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/json-schemas": "^6.1.3",
|
||||
"@0x/types": "^3.3.3",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "1.3.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "1.3.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "1.3.30",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "1.3.29",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "1.3.28",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.3.32 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.31 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.30 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.29 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.28 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-dev-utils",
|
||||
"version": "1.3.28",
|
||||
"version": "1.3.32",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -43,10 +43,10 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/assert": "^3.0.27",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "2.1.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "2.1.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "2.1.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "2.1.30",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "2.1.29",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.33 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.32 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.31 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.30 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.29 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc1155",
|
||||
"version": "2.1.29",
|
||||
"version": "2.1.33",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,7 +54,7 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -81,7 +81,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/utils": "^6.4.3",
|
||||
"@0x/web3-wrapper": "^7.5.3",
|
||||
"lodash": "^4.17.11"
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "3.3.12",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "3.3.11",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "3.3.10",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "3.3.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "3.3.8",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.3.12 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.3.11 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.3.10 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.3.9 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.3.8 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc20",
|
||||
"version": "3.3.8",
|
||||
"version": "3.3.12",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,8 +53,8 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "3.1.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "3.1.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "3.1.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "3.1.30",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "3.1.29",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.33 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.32 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.31 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.30 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.29 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc721",
|
||||
"version": "3.1.29",
|
||||
"version": "3.1.33",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,8 +54,8 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "4.2.34",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "4.2.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "4.2.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "4.2.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "4.2.30",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.2.34 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.33 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.32 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.31 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.30 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-forwarder",
|
||||
"version": "4.2.30",
|
||||
"version": "4.2.34",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,18 +53,18 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-dev-utils": "^1.3.28",
|
||||
"@0x/contracts-erc1155": "^2.1.29",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-erc721": "^3.1.29",
|
||||
"@0x/contracts-exchange": "^3.2.30",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-dev-utils": "^1.3.32",
|
||||
"@0x/contracts-erc1155": "^2.1.33",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-erc721": "^3.1.33",
|
||||
"@0x/contracts-exchange": "^3.2.34",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "4.3.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "4.3.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "4.3.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "4.3.30",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "4.3.29",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.3.33 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.32 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.31 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.30 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.29 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-libs",
|
||||
"version": "4.3.29",
|
||||
"version": "4.3.33",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -81,9 +81,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/types": "^3.3.3",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
"@0x/utils": "^6.4.3",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "3.2.34",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "3.2.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "3.2.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "3.2.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "3.2.30",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.34 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.33 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.32 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.31 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.30 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange",
|
||||
"version": "3.2.30",
|
||||
"version": "3.2.34",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,13 +53,13 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-multisig": "^4.1.30",
|
||||
"@0x/contracts-staking": "^2.0.37",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-multisig": "^4.1.34",
|
||||
"@0x/contracts-staking": "^2.0.41",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -89,11 +89,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.28",
|
||||
"@0x/contracts-erc1155": "^2.1.29",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-erc721": "^3.1.29",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/contracts-dev-utils": "^1.3.32",
|
||||
"@0x/contracts-erc1155": "^2.1.33",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-erc721": "^3.1.33",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/utils": "^6.4.3",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -13,7 +13,11 @@ export const exchangeDataEncoder = {
|
||||
.getABIEncodedTransactionData();
|
||||
} else if (constants.BATCH_FILL_FN_NAMES.indexOf(fnName) !== -1) {
|
||||
data = (exchangeInstance as any)
|
||||
[fnName](orders, orders.map(order => order.takerAssetAmount), orders.map(order => order.signature))
|
||||
[fnName](
|
||||
orders,
|
||||
orders.map(order => order.takerAssetAmount),
|
||||
orders.map(order => order.signature),
|
||||
)
|
||||
.getABIEncodedTransactionData();
|
||||
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) {
|
||||
const fillAsset = /Buy/.test(fnName) ? 'makerAssetAmount' : 'takerAssetAmount';
|
||||
|
@@ -39,7 +39,10 @@ blockchainTests.resets('Reentrancy Tests', env => {
|
||||
// Handle tuples.
|
||||
if (item.type === 'tuple') {
|
||||
const tuple = item as TupleDataItem;
|
||||
return _.zipObject(tuple.components.map(c => c.name), tuple.components.map(createFunctionInputs));
|
||||
return _.zipObject(
|
||||
tuple.components.map(c => c.name),
|
||||
tuple.components.map(createFunctionInputs),
|
||||
);
|
||||
}
|
||||
// Handle strings.
|
||||
if (item.type === 'string') {
|
||||
|
@@ -109,7 +109,11 @@ export class ExchangeWrapper {
|
||||
opts: { makerAssetFillAmount: BigNumber; gas?: number; gasPrice?: BigNumber },
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
return this.exchangeContract
|
||||
.marketBuyOrdersNoThrow(orders, opts.makerAssetFillAmount, orders.map(signedOrder => signedOrder.signature))
|
||||
.marketBuyOrdersNoThrow(
|
||||
orders,
|
||||
opts.makerAssetFillAmount,
|
||||
orders.map(signedOrder => signedOrder.signature),
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from, gas: opts.gas });
|
||||
}
|
||||
public async marketSellOrdersFillOrKillAsync(
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "6.2.28",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "6.2.27",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "6.2.26",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "6.2.25",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "6.2.24",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v6.2.28 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.27 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.26 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.25 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.24 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "6.2.24",
|
||||
"version": "6.2.28",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,16 +53,16 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-dev-utils": "^1.3.28",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-erc721": "^3.1.29",
|
||||
"@0x/contracts-exchange": "^3.2.30",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-dev-utils": "^1.3.32",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-erc721": "^3.1.33",
|
||||
"@0x/contracts-exchange": "^3.2.34",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
"ethereum-types": "^3.5.0"
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-integrations",
|
||||
"version": "2.7.40",
|
||||
"version": "2.7.49",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
@@ -53,21 +53,21 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contract-addresses": "^6.1.0",
|
||||
"@0x/contract-wrappers": "^13.16.1",
|
||||
"@0x/contracts-broker": "^1.1.29",
|
||||
"@0x/contracts-coordinator": "^3.1.30",
|
||||
"@0x/contracts-dev-utils": "^1.3.28",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.30",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/contracts-extensions": "^6.2.24",
|
||||
"@0x/contract-addresses": "^6.3.1",
|
||||
"@0x/contract-wrappers": "^13.17.1",
|
||||
"@0x/contracts-broker": "^1.1.33",
|
||||
"@0x/contracts-coordinator": "^3.1.34",
|
||||
"@0x/contracts-dev-utils": "^1.3.32",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.34",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/contracts-extensions": "^6.2.28",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/coordinator-server": "^1.0.5",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/migrations": "^8.0.6",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/protocol-utils": "^1.6.0",
|
||||
"@0x/migrations": "^8.0.10",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/protocol-utils": "^1.7.1",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
"@0x/web3-wrapper": "^7.5.3",
|
||||
@@ -93,17 +93,17 @@
|
||||
"typescript": "4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/asset-swapper": "^6.10.0",
|
||||
"@0x/asset-swapper": "^6.17.2",
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-erc1155": "^2.1.29",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-erc721": "^3.1.29",
|
||||
"@0x/contracts-exchange": "^3.2.30",
|
||||
"@0x/contracts-multisig": "^4.1.30",
|
||||
"@0x/contracts-staking": "^2.0.37",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-zero-ex": "^0.23.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-erc1155": "^2.1.33",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-erc721": "^3.1.33",
|
||||
"@0x/contracts-exchange": "^3.2.34",
|
||||
"@0x/contracts-multisig": "^4.1.34",
|
||||
"@0x/contracts-staking": "^2.0.41",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-zero-ex": "^0.25.1",
|
||||
"@0x/subproviders": "^6.5.3",
|
||||
"@0x/types": "^3.3.3",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
|
@@ -534,9 +534,14 @@ blockchainTests.skip('Coordinator Client', env => {
|
||||
const signedOrders = [signedOrder, signedOrderWithDifferentFeeRecipient];
|
||||
const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount];
|
||||
await coordinatorClient
|
||||
.batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), {
|
||||
from: takerAddress,
|
||||
})
|
||||
.batchFillOrdersAsync(
|
||||
signedOrders,
|
||||
takerAssetFillAmounts,
|
||||
signedOrders.map(o => o.signature),
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
)
|
||||
.then(res => {
|
||||
expect(res).to.be.undefined();
|
||||
})
|
||||
@@ -570,9 +575,14 @@ blockchainTests.skip('Coordinator Client', env => {
|
||||
const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator];
|
||||
const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount];
|
||||
await coordinatorClient
|
||||
.batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), {
|
||||
from: takerAddress,
|
||||
})
|
||||
.batchFillOrdersAsync(
|
||||
signedOrders,
|
||||
takerAssetFillAmounts,
|
||||
signedOrders.map(o => o.signature),
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
)
|
||||
.then(res => {
|
||||
expect(res).to.be.undefined();
|
||||
})
|
||||
@@ -600,9 +610,14 @@ blockchainTests.skip('Coordinator Client', env => {
|
||||
const signedOrders = [signedOrder, signedOrderWithDifferentCoordinatorOperator];
|
||||
const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount, takerTokenFillAmount];
|
||||
await coordinatorClient
|
||||
.batchFillOrdersAsync(signedOrders, takerAssetFillAmounts, signedOrders.map(o => o.signature), {
|
||||
from: takerAddress,
|
||||
})
|
||||
.batchFillOrdersAsync(
|
||||
signedOrders,
|
||||
takerAssetFillAmounts,
|
||||
signedOrders.map(o => o.signature),
|
||||
{
|
||||
from: takerAddress,
|
||||
},
|
||||
)
|
||||
.then(res => {
|
||||
expect(res).to.be.undefined();
|
||||
})
|
||||
|
@@ -267,7 +267,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
|
||||
expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value);
|
||||
await balanceStore.updateBalancesAsync();
|
||||
balanceStore.assertEquals(expectedBalances);
|
||||
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
|
||||
verifyEvents(
|
||||
txReceipt,
|
||||
orders.map(order => expectedFillEvent(order)),
|
||||
ExchangeEvents.Fill,
|
||||
);
|
||||
});
|
||||
it(`${fnName} should fill the orders if called by approver (eth fee, no refund)`, async () => {
|
||||
await balanceStore.updateBalancesAsync();
|
||||
@@ -280,7 +284,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
|
||||
expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value);
|
||||
await balanceStore.updateBalancesAsync();
|
||||
balanceStore.assertEquals(expectedBalances);
|
||||
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
|
||||
verifyEvents(
|
||||
txReceipt,
|
||||
orders.map(order => expectedFillEvent(order)),
|
||||
ExchangeEvents.Fill,
|
||||
);
|
||||
});
|
||||
it(`${fnName} should fill the orders if called by approver (mixed fees, refund)`, async () => {
|
||||
await balanceStore.updateBalancesAsync();
|
||||
@@ -293,7 +301,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
|
||||
expectedBalances.simulateFills(orders, taker.address, txReceipt, deployment, value);
|
||||
await balanceStore.updateBalancesAsync();
|
||||
balanceStore.assertEquals(expectedBalances);
|
||||
verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill);
|
||||
verifyEvents(
|
||||
txReceipt,
|
||||
orders.map(order => expectedFillEvent(order)),
|
||||
ExchangeEvents.Fill,
|
||||
);
|
||||
});
|
||||
it(`${fnName} should revert with an invalid approval signature`, async () => {
|
||||
const approvalSignature = hexUtils.concat(
|
||||
@@ -360,7 +372,11 @@ blockchainTests.resets('Coordinator integration tests', env => {
|
||||
.executeTransaction(transaction, maker.address, transaction.signature, [])
|
||||
.awaitTransactionSuccessAsync({ from: maker.address });
|
||||
|
||||
verifyEvents(txReceipt, orders.map(order => expectedCancelEvent(order)), ExchangeEvents.Cancel);
|
||||
verifyEvents(
|
||||
txReceipt,
|
||||
orders.map(order => expectedCancelEvent(order)),
|
||||
ExchangeEvents.Cancel,
|
||||
);
|
||||
});
|
||||
it('cancelOrdersUpTo call should be successful without an approval', async () => {
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrdersUpTo, []);
|
||||
|
@@ -186,13 +186,13 @@ blockchainTests.resets('LibAssetData', env => {
|
||||
});
|
||||
|
||||
it('should decode multiasset data', async () => {
|
||||
expect(await devUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData).callAsync()).to.deep.equal(
|
||||
[
|
||||
AssetProxyId.MultiAsset,
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts,
|
||||
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
|
||||
],
|
||||
);
|
||||
expect(
|
||||
await devUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData).callAsync(),
|
||||
).to.deep.equal([
|
||||
AssetProxyId.MultiAsset,
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts,
|
||||
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should encode StaticCall data', async () => {
|
||||
|
@@ -278,15 +278,21 @@ blockchainTests.resets('matchOrders integration tests', env => {
|
||||
ExchangeRevertErrors.BatchMatchOrdersErrorCodes.InvalidLengthRightSignatures,
|
||||
);
|
||||
let tx = deployment.exchange
|
||||
.batchMatchOrders(leftOrders, rightOrders, leftOrders.map(order => order.signature), [
|
||||
rightOrders[0].signature,
|
||||
])
|
||||
.batchMatchOrders(
|
||||
leftOrders,
|
||||
rightOrders,
|
||||
leftOrders.map(order => order.signature),
|
||||
[rightOrders[0].signature],
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: matcher.address });
|
||||
await expect(tx).to.revertWith(expectedError);
|
||||
tx = deployment.exchange
|
||||
.batchMatchOrdersWithMaximalFill(leftOrders, rightOrders, leftOrders.map(order => order.signature), [
|
||||
rightOrders[0].signature,
|
||||
])
|
||||
.batchMatchOrdersWithMaximalFill(
|
||||
leftOrders,
|
||||
rightOrders,
|
||||
leftOrders.map(order => order.signature),
|
||||
[rightOrders[0].signature],
|
||||
)
|
||||
.awaitTransactionSuccessAsync({ from: matcher.address });
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
@@ -475,7 +481,10 @@ blockchainTests.resets('matchOrders integration tests', env => {
|
||||
],
|
||||
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
|
||||
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT],
|
||||
matchIndices: [[0, 0], [1, 0]],
|
||||
matchIndices: [
|
||||
[0, 0],
|
||||
[1, 0],
|
||||
],
|
||||
shouldMaximallyFill: false,
|
||||
});
|
||||
});
|
||||
@@ -524,7 +533,10 @@ blockchainTests.resets('matchOrders integration tests', env => {
|
||||
],
|
||||
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT],
|
||||
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
|
||||
matchIndices: [[0, 0], [0, 1]],
|
||||
matchIndices: [
|
||||
[0, 0],
|
||||
[0, 1],
|
||||
],
|
||||
shouldMaximallyFill: false,
|
||||
});
|
||||
});
|
||||
@@ -626,7 +638,11 @@ blockchainTests.resets('matchOrders integration tests', env => {
|
||||
],
|
||||
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
|
||||
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
|
||||
matchIndices: [[0, 0], [0, 1], [1, 1]],
|
||||
matchIndices: [
|
||||
[0, 0],
|
||||
[0, 1],
|
||||
[1, 1],
|
||||
],
|
||||
shouldMaximallyFill: false,
|
||||
});
|
||||
});
|
||||
@@ -801,7 +817,11 @@ blockchainTests.resets('matchOrders integration tests', env => {
|
||||
],
|
||||
leftOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
|
||||
rightOrdersTakerAssetFilledAmounts: [constants.ZERO_AMOUNT, constants.ZERO_AMOUNT],
|
||||
matchIndices: [[0, 0], [1, 0], [1, 1]],
|
||||
matchIndices: [
|
||||
[0, 0],
|
||||
[1, 0],
|
||||
[1, 1],
|
||||
],
|
||||
shouldMaximallyFill: true,
|
||||
});
|
||||
});
|
||||
|
@@ -106,7 +106,12 @@ blockchainTests.fork.resets('Forwarder mainnet tests', env => {
|
||||
orders[1].takerAssetAmount.dividedToIntegerBy(2),
|
||||
);
|
||||
const [wethSpentAmount, makerAssetAcquiredAmount] = await forwarder
|
||||
.marketSellOrdersWithEth(orders, orders.map(o => o.signature), [], [])
|
||||
.marketSellOrdersWithEth(
|
||||
orders,
|
||||
orders.map(o => o.signature),
|
||||
[],
|
||||
[],
|
||||
)
|
||||
.callAsync({
|
||||
from: takerAddress,
|
||||
value: ethSellAmount,
|
||||
@@ -161,7 +166,13 @@ blockchainTests.fork.resets('Forwarder mainnet tests', env => {
|
||||
orders[1].makerAssetAmount.dividedToIntegerBy(2),
|
||||
);
|
||||
const [wethSpentAmount, makerAssetAcquiredAmount] = await forwarder
|
||||
.marketBuyOrdersWithEth(orders, makerAssetBuyAmount, orders.map(o => o.signature), [], [])
|
||||
.marketBuyOrdersWithEth(
|
||||
orders,
|
||||
makerAssetBuyAmount,
|
||||
orders.map(o => o.signature),
|
||||
[],
|
||||
[],
|
||||
)
|
||||
.callAsync({
|
||||
from: takerAddress,
|
||||
value: ethSellAmount,
|
||||
|
@@ -190,9 +190,14 @@ export function MakerMixin<TBase extends Constructor>(Base: TBase): TBase & Cons
|
||||
rightTakerAssetData,
|
||||
makerFeeAssetData,
|
||||
takerFeeAssetData,
|
||||
] = [leftMakerToken, leftTakerToken, rightMakerToken, rightTakerToken, makerFeeToken, takerFeeToken].map(
|
||||
token => encodeERC20AssetData(token.address),
|
||||
);
|
||||
] = [
|
||||
leftMakerToken,
|
||||
leftTakerToken,
|
||||
rightMakerToken,
|
||||
rightTakerToken,
|
||||
makerFeeToken,
|
||||
takerFeeToken,
|
||||
].map(token => encodeERC20AssetData(token.address));
|
||||
|
||||
// Construct and sign the left order
|
||||
const leftOrder = await this.signOrderAsync({
|
||||
|
@@ -8,7 +8,10 @@ import { Actor, Constructor } from './base';
|
||||
* Useful for BalanceStore.
|
||||
*/
|
||||
export function actorAddressesByName(actors: Actor[]): ObjectMap<string> {
|
||||
return _.zipObject(actors.map(actor => actor.name), actors.map(actor => actor.address));
|
||||
return _.zipObject(
|
||||
actors.map(actor => actor.name),
|
||||
actors.map(actor => actor.address),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -77,19 +77,24 @@ tests('Exchange signature validation fuzz tests', env => {
|
||||
before(async () => {
|
||||
chainId = await env.web3Wrapper.getChainIdAsync();
|
||||
accounts = await env.getAccountAddressesAsync();
|
||||
privateKeys = _.zipObject(accounts, accounts.map((a, i) => constants.TESTRPC_PRIVATE_KEYS[i]));
|
||||
privateKeys = _.zipObject(
|
||||
accounts,
|
||||
accounts.map((a, i) => constants.TESTRPC_PRIVATE_KEYS[i]),
|
||||
);
|
||||
deployment = await DeploymentManager.deployAsync(env, {
|
||||
numErc20TokensToDeploy: 0,
|
||||
numErc721TokensToDeploy: 0,
|
||||
numErc1155TokensToDeploy: 0,
|
||||
});
|
||||
exchange = deployment.exchange;
|
||||
walletContractAddress = (await TestSignatureValidationWalletContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestSignatureValidationWallet,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
)).address;
|
||||
walletContractAddress = (
|
||||
await TestSignatureValidationWalletContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestSignatureValidationWallet,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
)
|
||||
).address;
|
||||
// This just has to be a contract address that doesn't implement the
|
||||
// wallet spec.
|
||||
notWalletContractAddress = exchange.address;
|
||||
@@ -715,7 +720,7 @@ tests('Exchange signature validation fuzz tests', env => {
|
||||
invalidTestTransactionMangledSignature(),
|
||||
];
|
||||
const simulationEnvironment = new SimulationEnvironment(deployment, new BlockchainBalanceStore({}, {}), []);
|
||||
const simulation = new class extends Simulation {
|
||||
const simulation = new (class extends Simulation {
|
||||
// tslint:disable-next-line: prefer-function-over-method
|
||||
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {
|
||||
while (true) {
|
||||
@@ -723,7 +728,7 @@ tests('Exchange signature validation fuzz tests', env => {
|
||||
yield (await action!.next()).value;
|
||||
}
|
||||
}
|
||||
}(simulationEnvironment);
|
||||
})(simulationEnvironment);
|
||||
simulation.resets = true;
|
||||
return simulation.fuzzAsync();
|
||||
});
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "4.1.34",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "4.1.33",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "4.1.32",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "4.1.31",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "4.1.30",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.1.34 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.33 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.32 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.31 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.30 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-multisig",
|
||||
"version": "4.1.30",
|
||||
"version": "4.1.34",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -50,11 +50,11 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "2.0.41",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "2.0.40",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "2.0.39",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "2.0.38",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.0.37",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.0.41 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.40 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.39 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.38 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.37 - _May 5, 2021_
|
||||
|
||||
* Patch epoch finalization issue (#221)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-staking",
|
||||
"version": "2.0.37",
|
||||
"version": "2.0.41",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,14 +54,14 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-dev-utils": "^1.3.28",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.29",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-dev-utils": "^1.3.32",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-exchange-libs": "^4.3.33",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-utils": "^4.7.8",
|
||||
"@0x/contracts-utils": "^4.7.12",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
@@ -88,7 +88,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
"@0x/utils": "^6.4.3",
|
||||
"ethereum-types": "^3.5.0",
|
||||
|
@@ -157,11 +157,11 @@ export class FinalizerActor extends BaseActor {
|
||||
const delegators = delegatorsByPoolId[poolId];
|
||||
delegatorBalancesByPoolId[poolId] = {};
|
||||
for (const delegator of delegators) {
|
||||
delegatorBalancesByPoolId[poolId][
|
||||
delegator
|
||||
] = (await this._stakingApiWrapper.stakingContract
|
||||
.getStakeDelegatedToPoolByOwner(delegator, poolId)
|
||||
.callAsync()).currentEpochBalance;
|
||||
delegatorBalancesByPoolId[poolId][delegator] = (
|
||||
await this._stakingApiWrapper.stakingContract
|
||||
.getStakeDelegatedToPoolByOwner(delegator, poolId)
|
||||
.callAsync()
|
||||
).currentEpochBalance;
|
||||
}
|
||||
}
|
||||
return delegatorBalancesByPoolId;
|
||||
@@ -253,7 +253,10 @@ export class FinalizerActor extends BaseActor {
|
||||
const totalFeesCollected = BigNumber.sum(...activePools.map(p => p.feesCollected));
|
||||
const totalWeightedStake = BigNumber.sum(...activePools.map(p => p.weightedStake));
|
||||
if (totalRewards.eq(0) || totalFeesCollected.eq(0) || totalWeightedStake.eq(0)) {
|
||||
return _.zipObject(poolIds, _.times(poolIds.length, () => new BigNumber(0)));
|
||||
return _.zipObject(
|
||||
poolIds,
|
||||
_.times(poolIds.length, () => new BigNumber(0)),
|
||||
);
|
||||
}
|
||||
const rewards = await Promise.all(
|
||||
activePools.map(async pool =>
|
||||
|
@@ -102,13 +102,15 @@ blockchainTests('Migration tests', env => {
|
||||
});
|
||||
|
||||
it('should set the correct initial params', async () => {
|
||||
const stakingProxyContractAddress = (await StakingProxyContract.deployFrom0xArtifactAsync(
|
||||
artifacts.StakingProxy,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
stakingContract.address,
|
||||
)).address;
|
||||
const stakingProxyContractAddress = (
|
||||
await StakingProxyContract.deployFrom0xArtifactAsync(
|
||||
artifacts.StakingProxy,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
stakingContract.address,
|
||||
)
|
||||
).address;
|
||||
|
||||
const stakingProxyContract = new StakingContract(
|
||||
stakingProxyContractAddress,
|
||||
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "5.4.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "5.4.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "5.4.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "5.4.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "5.4.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v5.4.4 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.4.3 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.4.2 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.4.1 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.4.0 - _May 5, 2021_
|
||||
|
||||
* Set default ganache gas limit to 100e6 (#197)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-test-utils",
|
||||
"version": "5.4.0",
|
||||
"version": "5.4.4",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -44,10 +44,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.27",
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/contract-addresses": "^6.1.0",
|
||||
"@0x/contract-addresses": "^6.3.1",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/json-schemas": "^6.1.3",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/sol-coverage": "^4.0.37",
|
||||
"@0x/sol-profiler": "^4.1.27",
|
||||
"@0x/sol-trace": "^3.0.37",
|
||||
|
@@ -108,9 +108,7 @@ export async function testWithReferenceFuncAsync(
|
||||
return expect.fail(
|
||||
actualError,
|
||||
expectedError,
|
||||
`${testCaseString}: expected error message '${actualError.message}' to equal '${
|
||||
expectedError.message
|
||||
}'`,
|
||||
`${testCaseString}: expected error message '${actualError.message}' to equal '${expectedError.message}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,50 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "1.2.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "1.2.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added proposal 0 params and test",
|
||||
"pr": 252
|
||||
}
|
||||
],
|
||||
"timestamp": 1622154125
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "1.1.8",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "1.1.7",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "1.1.6",
|
||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.2.2 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.2.1 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.2.0 - _May 27, 2021_
|
||||
|
||||
* Added proposal 0 params and test (#252)
|
||||
|
||||
## v1.1.8 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.7 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.6 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-treasury",
|
||||
"version": "1.1.6",
|
||||
"version": "1.2.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -47,12 +47,12 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contract-addresses": "^6.1.0",
|
||||
"@0x/contracts-asset-proxy": "^3.7.11",
|
||||
"@0x/contracts-erc20": "^3.3.8",
|
||||
"@0x/contract-addresses": "^6.3.1",
|
||||
"@0x/contracts-asset-proxy": "^3.7.15",
|
||||
"@0x/contracts-erc20": "^3.3.12",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-staking": "^2.0.37",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-staking": "^2.0.41",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
@@ -73,7 +73,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.4.0",
|
||||
"@0x/protocol-utils": "^1.6.0",
|
||||
"@0x/protocol-utils": "^1.7.1",
|
||||
"@0x/subproviders": "^6.5.3",
|
||||
"@0x/types": "^3.3.3",
|
||||
"@0x/typescript-typings": "^5.2.0",
|
||||
|
35
contracts/treasury/src/proposals.ts
Normal file
35
contracts/treasury/src/proposals.ts
Normal file
File diff suppressed because one or more lines are too long
154
contracts/treasury/test/proposal_test.ts
Normal file
154
contracts/treasury/test/proposal_test.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import { artifacts as erc20Artifacts, ERC20TokenEvents } from '@0x/contracts-erc20';
|
||||
import { StakingContract, StakingProxyContract } from '@0x/contracts-staking';
|
||||
import { blockchainTests, constants, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, hexUtils, logUtils } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { proposals } from '../src/proposals';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { ZrxTreasuryContract, ZrxTreasuryEvents } from './wrappers';
|
||||
|
||||
const SUBGRAPH_URL = 'https://api.thegraph.com/subgraphs/name/mzhu25/zeroex-staking';
|
||||
const STAKING_PROXY_ADDRESS = '0xa26e80e7dea86279c6d778d702cc413e6cffa777';
|
||||
const TREASURY_ADDRESS = '0x0bb1810061c2f5b2088054ee184e6c79e1591101';
|
||||
const PROPOSER = process.env.PROPOSER || constants.NULL_ADDRESS;
|
||||
const VOTER = '0xba4f44e774158408e2dc6c5cb65bc995f0a89180';
|
||||
const VOTER_OPERATED_POOLS = ['0x0000000000000000000000000000000000000000000000000000000000000017'];
|
||||
blockchainTests.configure({
|
||||
fork: {
|
||||
unlockedAccounts: [PROPOSER, VOTER],
|
||||
},
|
||||
});
|
||||
|
||||
async function querySubgraphAsync(operatorAddress: string): Promise<string[]> {
|
||||
const query = `
|
||||
{
|
||||
stakingActor(id: "${operatorAddress}") {
|
||||
operatedPools {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const response = await fetch(SUBGRAPH_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query,
|
||||
}),
|
||||
});
|
||||
const {
|
||||
data: { stakingActor },
|
||||
} = await response.json();
|
||||
if (stakingActor) {
|
||||
return stakingActor.operatedPools.map((pool: { id: string }) => hexUtils.leftPad(pool.id));
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
blockchainTests.fork.skip('Treasury proposal mainnet fork tests', env => {
|
||||
let staking: StakingContract;
|
||||
let stakingProxy: StakingProxyContract;
|
||||
let treasury: ZrxTreasuryContract;
|
||||
let votingPeriod: BigNumber;
|
||||
|
||||
async function fastForwardToNextEpochAsync(): Promise<void> {
|
||||
const epochEndTime = await staking.getCurrentEpochEarliestEndTimeInSeconds().callAsync();
|
||||
const lastBlockTime = await env.web3Wrapper.getBlockTimestampAsync('latest');
|
||||
const dt = Math.max(0, epochEndTime.minus(lastBlockTime).toNumber());
|
||||
await env.web3Wrapper.increaseTimeAsync(dt);
|
||||
// mine next block
|
||||
await env.web3Wrapper.mineBlockAsync();
|
||||
const lastPoolId = new BigNumber(await staking.lastPoolId().callAsync(), 16);
|
||||
const batchExecuteCalldata = [
|
||||
...[...new Array(lastPoolId.toNumber())].map((_x, i) =>
|
||||
staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(),
|
||||
),
|
||||
staking.endEpoch().getABIEncodedTransactionData(),
|
||||
...[...new Array(lastPoolId.toNumber())].map((_x, i) =>
|
||||
staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(),
|
||||
),
|
||||
...[...new Array(lastPoolId.toNumber())].map((_x, i) =>
|
||||
staking.finalizePool(hexUtils.leftPad(i + 1)).getABIEncodedTransactionData(),
|
||||
),
|
||||
];
|
||||
await stakingProxy.batchExecute(batchExecuteCalldata).awaitTransactionSuccessAsync();
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
const abis = _.mapValues({ ...artifacts, ...erc20Artifacts }, v => v.compilerOutput.abi);
|
||||
treasury = new ZrxTreasuryContract(TREASURY_ADDRESS, env.provider, env.txDefaults, abis);
|
||||
votingPeriod = await treasury.votingPeriod().callAsync();
|
||||
staking = new StakingContract(STAKING_PROXY_ADDRESS, env.provider, env.txDefaults);
|
||||
stakingProxy = new StakingProxyContract(STAKING_PROXY_ADDRESS, env.provider, env.txDefaults);
|
||||
});
|
||||
|
||||
describe('Proposal 0', () => {
|
||||
it('works', async () => {
|
||||
const proposal = proposals[0];
|
||||
let executionEpoch: BigNumber;
|
||||
if (proposal.executionEpoch) {
|
||||
executionEpoch = proposal.executionEpoch;
|
||||
} else {
|
||||
const currentEpoch = await staking.currentEpoch().callAsync();
|
||||
executionEpoch = currentEpoch.plus(2);
|
||||
}
|
||||
const pools = await querySubgraphAsync(PROPOSER);
|
||||
const proposeTx = treasury.propose(proposal.actions, executionEpoch, proposal.description, pools);
|
||||
|
||||
const calldata = proposeTx.getABIEncodedTransactionData();
|
||||
logUtils.log('ZrxTreasury.propose calldata:');
|
||||
logUtils.log(calldata);
|
||||
|
||||
const proposalId = await proposeTx.callAsync({ from: PROPOSER });
|
||||
const receipt = await proposeTx.awaitTransactionSuccessAsync({ from: PROPOSER });
|
||||
verifyEventsFromLogs(
|
||||
receipt.logs,
|
||||
[
|
||||
{
|
||||
...proposal,
|
||||
proposalId,
|
||||
executionEpoch,
|
||||
proposer: PROPOSER,
|
||||
operatedPoolIds: pools,
|
||||
},
|
||||
],
|
||||
ZrxTreasuryEvents.ProposalCreated,
|
||||
);
|
||||
await fastForwardToNextEpochAsync();
|
||||
await fastForwardToNextEpochAsync();
|
||||
await treasury
|
||||
.castVote(proposalId, true, VOTER_OPERATED_POOLS)
|
||||
.awaitTransactionSuccessAsync({ from: VOTER });
|
||||
await env.web3Wrapper.increaseTimeAsync(votingPeriod.plus(1).toNumber());
|
||||
await env.web3Wrapper.mineBlockAsync();
|
||||
const executeTx = await treasury.execute(proposalId, proposal.actions).awaitTransactionSuccessAsync();
|
||||
verifyEventsFromLogs(
|
||||
executeTx.logs,
|
||||
[
|
||||
{
|
||||
proposalId,
|
||||
},
|
||||
],
|
||||
ZrxTreasuryEvents.ProposalExecuted,
|
||||
);
|
||||
const recipient = '0xf9347f751a6a1467abc722ec7d80ba2698dd9d6c';
|
||||
verifyEventsFromLogs(
|
||||
executeTx.logs,
|
||||
[
|
||||
{
|
||||
_from: TREASURY_ADDRESS,
|
||||
_to: recipient,
|
||||
_value: new BigNumber(400_000).times('1e18'),
|
||||
},
|
||||
],
|
||||
ERC20TokenEvents.Transfer,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "4.7.12",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1622609597,
|
||||
"version": "4.7.11",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "4.7.10",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1621600614,
|
||||
"version": "4.7.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1620214333,
|
||||
"version": "4.7.8",
|
||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.7.12 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.7.11 - _June 2, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.7.10 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.7.9 - _May 21, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.7.8 - _May 5, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-utils",
|
||||
"version": "4.7.8",
|
||||
"version": "4.7.12",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,9 +52,9 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.6.0",
|
||||
"@0x/contracts-gen": "^2.0.38",
|
||||
"@0x/contracts-test-utils": "^5.4.0",
|
||||
"@0x/contracts-test-utils": "^5.4.4",
|
||||
"@0x/dev-utils": "^4.2.7",
|
||||
"@0x/order-utils": "^10.4.21",
|
||||
"@0x/order-utils": "^10.4.25",
|
||||
"@0x/sol-compiler": "^4.7.3",
|
||||
"@0x/tslint-config": "^4.1.4",
|
||||
"@0x/types": "^3.3.3",
|
||||
|
@@ -536,7 +536,11 @@ blockchainTests('LibBytes', env => {
|
||||
]));
|
||||
|
||||
describe('copies forward within one word and one byte overlap', () =>
|
||||
test([[0, 0, 1, 'one byte'], [10, 0, 11, 'eleven bytes'], [15, 0, 16, 'sixteen bytes']]));
|
||||
test([
|
||||
[0, 0, 1, 'one byte'],
|
||||
[10, 0, 11, 'eleven bytes'],
|
||||
[15, 0, 16, 'sixteen bytes'],
|
||||
]));
|
||||
|
||||
describe('copies backward', () =>
|
||||
test([
|
||||
@@ -603,7 +607,11 @@ blockchainTests('LibBytes', env => {
|
||||
]));
|
||||
|
||||
describe('copies forward within one word and one byte overlap', () =>
|
||||
test([[0, 0, 1, 'one byte'], [0, 10, 11, 'eleven bytes'], [0, 15, 16, 'sixteen bytes']]));
|
||||
test([
|
||||
[0, 0, 1, 'one byte'],
|
||||
[0, 10, 11, 'eleven bytes'],
|
||||
[0, 15, 16, 'sixteen bytes'],
|
||||
]));
|
||||
});
|
||||
|
||||
describe('slice', () => {
|
||||
|
@@ -1,4 +1,46 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1623382456,
|
||||
"version": "0.25.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.25.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add OtcOrdersFeature",
|
||||
"pr": 244
|
||||
},
|
||||
{
|
||||
"note": "Add UniswapV3 VIP feature",
|
||||
"pr": 237
|
||||
}
|
||||
],
|
||||
"timestamp": 1622609597
|
||||
},
|
||||
{
|
||||
"timestamp": 1621944788,
|
||||
"version": "0.24.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.24.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add special selectors to selector collision test",
|
||||
"pr": 243
|
||||
}
|
||||
],
|
||||
"timestamp": 1621600614
|
||||
},
|
||||
{
|
||||
"version": "0.23.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,23 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.25.1 - _June 11, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.25.0 - _June 2, 2021_
|
||||
|
||||
* Add OtcOrdersFeature (#244)
|
||||
* Add UniswapV3 VIP feature (#237)
|
||||
|
||||
## v0.24.1 - _May 25, 2021_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.24.0 - _May 21, 2021_
|
||||
|
||||
* Add special selectors to selector collision test (#243)
|
||||
|
||||
## v0.23.0 - _May 5, 2021_
|
||||
|
||||
* Added ETH support to `MixinCurve` (#220)
|
||||
|
@@ -26,11 +26,13 @@ import "./features/interfaces/ITokenSpenderFeature.sol";
|
||||
import "./features/interfaces/ITransformERC20Feature.sol";
|
||||
import "./features/interfaces/IMetaTransactionsFeature.sol";
|
||||
import "./features/interfaces/IUniswapFeature.sol";
|
||||
import "./features/interfaces/IUniswapV3Feature.sol";
|
||||
import "./features/interfaces/IPancakeSwapFeature.sol";
|
||||
import "./features/interfaces/ILiquidityProviderFeature.sol";
|
||||
import "./features/interfaces/INativeOrdersFeature.sol";
|
||||
import "./features/interfaces/IBatchFillNativeOrdersFeature.sol";
|
||||
import "./features/interfaces/IMultiplexFeature.sol";
|
||||
import "./features/interfaces/IOtcOrdersFeature.sol";
|
||||
|
||||
|
||||
/// @dev Interface for a fully featured Exchange Proxy.
|
||||
@@ -40,11 +42,13 @@ interface IZeroEx is
|
||||
ITransformERC20Feature,
|
||||
IMetaTransactionsFeature,
|
||||
IUniswapFeature,
|
||||
IUniswapV3Feature,
|
||||
IPancakeSwapFeature,
|
||||
ILiquidityProviderFeature,
|
||||
INativeOrdersFeature,
|
||||
IBatchFillNativeOrdersFeature,
|
||||
IMultiplexFeature
|
||||
IMultiplexFeature,
|
||||
IOtcOrdersFeature
|
||||
{
|
||||
// solhint-disable state-visibility
|
||||
|
||||
|
@@ -88,6 +88,23 @@ library LibNativeOrdersRichErrors {
|
||||
);
|
||||
}
|
||||
|
||||
function OrderNotSignedByTakerError(
|
||||
bytes32 orderHash,
|
||||
address signer,
|
||||
address taker
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory)
|
||||
{
|
||||
return abi.encodeWithSelector(
|
||||
bytes4(keccak256("OrderNotSignedByTakerError(bytes32,address,address)")),
|
||||
orderHash,
|
||||
signer,
|
||||
taker
|
||||
);
|
||||
}
|
||||
|
||||
function InvalidSignerError(
|
||||
address maker,
|
||||
address signer
|
||||
|
@@ -108,7 +108,7 @@ contract LiquidityProviderFeature is
|
||||
|
||||
if (!LibERC20Transformer.isTokenETH(inputToken)) {
|
||||
// Transfer input ERC20 tokens to the provider.
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
inputToken,
|
||||
msg.sender,
|
||||
address(provider),
|
||||
|
@@ -251,7 +251,7 @@ contract MetaTransactionsFeature is
|
||||
|
||||
// Pay the fee to the sender.
|
||||
if (state.mtx.feeAmount > 0) {
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
state.mtx.feeToken,
|
||||
state.mtx.signer,
|
||||
state.sender,
|
||||
|
@@ -36,6 +36,7 @@ import "./interfaces/IFeature.sol";
|
||||
import "./interfaces/IMultiplexFeature.sol";
|
||||
import "./interfaces/INativeOrdersFeature.sol";
|
||||
import "./interfaces/ITransformERC20Feature.sol";
|
||||
import "./interfaces/IUniswapV3Feature.sol";
|
||||
import "./libs/LibNativeOrder.sol";
|
||||
|
||||
|
||||
@@ -55,7 +56,7 @@ contract MultiplexFeature is
|
||||
/// @dev Name of this feature.
|
||||
string public constant override FEATURE_NAME = "MultiplexFeature";
|
||||
/// @dev Version of this feature.
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 1);
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
|
||||
|
||||
/// @dev The WETH token contract.
|
||||
IEtherTokenV06 private immutable weth;
|
||||
@@ -273,6 +274,22 @@ contract MultiplexFeature is
|
||||
// Increment the sold and bought amounts.
|
||||
soldAmount = soldAmount.safeAdd(inputTokenAmount);
|
||||
outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_);
|
||||
} else if (wrappedCall.selector == IUniswapV3Feature.sellTokenForTokenToUniswapV3.selector) {
|
||||
(bool success, bytes memory resultData) = address(this).delegatecall(
|
||||
abi.encodeWithSelector(
|
||||
IUniswapV3Feature.sellTokenForTokenToUniswapV3.selector,
|
||||
wrappedCall.data,
|
||||
inputTokenAmount,
|
||||
0,
|
||||
msg.sender
|
||||
)
|
||||
);
|
||||
if (success) {
|
||||
uint256 outputTokenAmount_ = abi.decode(resultData, (uint256));
|
||||
// Increment the sold and bought amounts.
|
||||
soldAmount = soldAmount.safeAdd(inputTokenAmount);
|
||||
outputTokenAmount = outputTokenAmount.safeAdd(outputTokenAmount_);
|
||||
}
|
||||
} else if (wrappedCall.selector == this._sellToLiquidityProvider.selector) {
|
||||
(address provider, bytes memory auxiliaryData) = abi.decode(
|
||||
wrappedCall.data,
|
||||
@@ -289,7 +306,7 @@ contract MultiplexFeature is
|
||||
remainingEth -= inputTokenAmount;
|
||||
} else {
|
||||
// Transfer input ERC20 tokens to the provider.
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
fillData.inputToken,
|
||||
msg.sender,
|
||||
provider,
|
||||
@@ -453,7 +470,7 @@ contract MultiplexFeature is
|
||||
_transferEth(payable(provider), outputTokenAmount);
|
||||
remainingEth -= outputTokenAmount;
|
||||
} else {
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
IERC20TokenV06(fillData.tokens[i]),
|
||||
msg.sender,
|
||||
provider,
|
||||
@@ -512,7 +529,7 @@ contract MultiplexFeature is
|
||||
// send the output token to some address other than
|
||||
// msg.sender, so we must transfer the input token
|
||||
// to the FlashWallet here.
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
args.inputToken,
|
||||
msg.sender,
|
||||
flashWallet,
|
||||
@@ -598,7 +615,7 @@ contract MultiplexFeature is
|
||||
|
||||
if (pairAddress == address(0)) {
|
||||
pairAddress = _computeUniswapPairAddress(tokens[0], tokens[1], isSushi);
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
IERC20TokenV06(tokens[0]),
|
||||
msg.sender,
|
||||
pairAddress,
|
||||
|
472
contracts/zero-ex/contracts/src/features/OtcOrdersFeature.sol
Normal file
472
contracts/zero-ex/contracts/src/features/OtcOrdersFeature.sol
Normal file
@@ -0,0 +1,472 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2021 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
|
||||
import "../errors/LibNativeOrdersRichErrors.sol";
|
||||
import "../fixins/FixinCommon.sol";
|
||||
import "../fixins/FixinEIP712.sol";
|
||||
import "../fixins/FixinTokenSpender.sol";
|
||||
import "../migrations/LibMigrate.sol";
|
||||
import "../storage/LibNativeOrdersStorage.sol";
|
||||
import "../storage/LibOtcOrdersStorage.sol";
|
||||
import "./interfaces/IFeature.sol";
|
||||
import "./interfaces/IOtcOrdersFeature.sol";
|
||||
import "./libs/LibNativeOrder.sol";
|
||||
import "./libs/LibSignature.sol";
|
||||
|
||||
|
||||
/// @dev Feature for interacting with OTC orders.
|
||||
contract OtcOrdersFeature is
|
||||
IFeature,
|
||||
IOtcOrdersFeature,
|
||||
FixinCommon,
|
||||
FixinEIP712,
|
||||
FixinTokenSpender
|
||||
{
|
||||
using LibSafeMathV06 for uint256;
|
||||
using LibSafeMathV06 for uint128;
|
||||
|
||||
/// @dev Options for handling ETH/WETH conversion
|
||||
/// @param LeaveAsWeth Neither unwrap nor wrap.
|
||||
/// @param WrapEth Wrap attached ETH.
|
||||
/// @param UnwrapWeth Unwrap WETH before transferring
|
||||
/// to taker.
|
||||
enum WethOptions {
|
||||
LeaveAsWeth,
|
||||
WrapEth,
|
||||
UnwrapWeth
|
||||
}
|
||||
|
||||
/// @dev Name of this feature.
|
||||
string public constant override FEATURE_NAME = "OtcOrders";
|
||||
/// @dev Version of this feature.
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
||||
/// @dev The WETH token contract.
|
||||
IEtherTokenV06 private immutable WETH;
|
||||
|
||||
constructor(address zeroExAddress, IEtherTokenV06 weth)
|
||||
public
|
||||
FixinEIP712(zeroExAddress)
|
||||
{
|
||||
WETH = weth;
|
||||
}
|
||||
|
||||
/// @dev Initialize and register this feature.
|
||||
/// Should be delegatecalled by `Migrate.migrate()`.
|
||||
/// @return success `LibMigrate.SUCCESS` on success.
|
||||
function migrate()
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
_registerFeatureFunction(this.fillOtcOrder.selector);
|
||||
_registerFeatureFunction(this.fillOtcOrderWithEth.selector);
|
||||
_registerFeatureFunction(this.fillTakerSignedOtcOrder.selector);
|
||||
_registerFeatureFunction(this.getOtcOrderInfo.selector);
|
||||
_registerFeatureFunction(this.getOtcOrderHash.selector);
|
||||
_registerFeatureFunction(this.lastOtcTxOriginNonce.selector);
|
||||
return LibMigrate.MIGRATE_SUCCESS;
|
||||
}
|
||||
|
||||
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @param takerTokenFillAmount Maximum taker token amount to fill this
|
||||
/// order with.
|
||||
/// @param unwrapWeth Whether or not to unwrap bought WETH into ETH
|
||||
/// before transferring it to the taker. Should be set to false
|
||||
/// if the maker token is not WETH.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function fillOtcOrder(
|
||||
LibNativeOrder.OtcOrder memory order,
|
||||
LibSignature.Signature memory makerSignature,
|
||||
uint128 takerTokenFillAmount,
|
||||
bool unwrapWeth
|
||||
)
|
||||
public
|
||||
override
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
if (!_isSenderValidTaker(order.taker)) {
|
||||
bytes32 orderHash = getOtcOrderHash(order);
|
||||
LibNativeOrdersRichErrors.OrderNotFillableByTakerError(
|
||||
orderHash,
|
||||
msg.sender,
|
||||
order.taker
|
||||
).rrevert();
|
||||
}
|
||||
LibSignature.Signature memory nullSignature;
|
||||
return _fillOtcOrderPrivate(
|
||||
order,
|
||||
makerSignature,
|
||||
nullSignature,
|
||||
takerTokenFillAmount,
|
||||
unwrapWeth ? WethOptions.UnwrapWeth : WethOptions.LeaveAsWeth
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Fill an OTC order whose taker token is WETH for up
|
||||
/// to `msg.value`.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function fillOtcOrderWithEth(
|
||||
LibNativeOrder.OtcOrder memory order,
|
||||
LibSignature.Signature memory makerSignature
|
||||
)
|
||||
public
|
||||
override
|
||||
payable
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
if (!_isSenderValidTaker(order.taker)) {
|
||||
bytes32 orderHash = getOtcOrderHash(order);
|
||||
LibNativeOrdersRichErrors.OrderNotFillableByTakerError(
|
||||
orderHash,
|
||||
msg.sender,
|
||||
order.taker
|
||||
).rrevert();
|
||||
}
|
||||
LibSignature.Signature memory nullSignature;
|
||||
return _fillOtcOrderPrivate(
|
||||
order,
|
||||
makerSignature,
|
||||
nullSignature,
|
||||
msg.value.safeDowncastToUint128(),
|
||||
WethOptions.WrapEth
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Fully fill an OTC order. "Meta-transaction" variant,
|
||||
/// requires order to be signed by both maker and taker.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @param takerSignature The order signature from the taker.
|
||||
/// @param unwrapWeth Whether or not to unwrap bought WETH into ETH
|
||||
/// before transferring it to the taker. Should be set to false
|
||||
/// if the maker token is not WETH.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function fillTakerSignedOtcOrder(
|
||||
LibNativeOrder.OtcOrder memory order,
|
||||
LibSignature.Signature memory makerSignature,
|
||||
LibSignature.Signature memory takerSignature,
|
||||
bool unwrapWeth
|
||||
)
|
||||
public
|
||||
override
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
return _fillOtcOrderPrivate(
|
||||
order,
|
||||
makerSignature,
|
||||
takerSignature,
|
||||
order.takerAmount,
|
||||
unwrapWeth ? WethOptions.UnwrapWeth : WethOptions.LeaveAsWeth
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Fill an OTC order. Private variant.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @param takerSignature The order signature from the taker.
|
||||
/// Ignored if msg.sender == order.taker.
|
||||
/// @param takerTokenFillAmount Maximum taker token amount to
|
||||
/// fill this order with.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function _fillOtcOrderPrivate(
|
||||
LibNativeOrder.OtcOrder memory order,
|
||||
LibSignature.Signature memory makerSignature,
|
||||
LibSignature.Signature memory takerSignature,
|
||||
uint128 takerTokenFillAmount,
|
||||
WethOptions wethOptions
|
||||
)
|
||||
private
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
LibNativeOrder.OtcOrderInfo memory orderInfo = getOtcOrderInfo(order);
|
||||
|
||||
// Must be fillable.
|
||||
if (orderInfo.status != LibNativeOrder.OrderStatus.FILLABLE) {
|
||||
LibNativeOrdersRichErrors.OrderNotFillableError(
|
||||
orderInfo.orderHash,
|
||||
uint8(orderInfo.status)
|
||||
).rrevert();
|
||||
}
|
||||
|
||||
address taker = msg.sender;
|
||||
{
|
||||
LibNativeOrdersStorage.Storage storage stor =
|
||||
LibNativeOrdersStorage.getStorage();
|
||||
|
||||
// Must be fillable by the tx.origin.
|
||||
if (
|
||||
order.txOrigin != tx.origin &&
|
||||
!stor.originRegistry[order.txOrigin][tx.origin]
|
||||
) {
|
||||
LibNativeOrdersRichErrors.OrderNotFillableByOriginError(
|
||||
orderInfo.orderHash,
|
||||
tx.origin,
|
||||
order.txOrigin
|
||||
).rrevert();
|
||||
}
|
||||
|
||||
// Maker signature must be valid for the order.
|
||||
address makerSigner = LibSignature.getSignerOfHash(orderInfo.orderHash, makerSignature);
|
||||
if (
|
||||
makerSigner != order.maker &&
|
||||
!stor.orderSignerRegistry[order.maker][makerSigner]
|
||||
) {
|
||||
LibNativeOrdersRichErrors.OrderNotSignedByMakerError(
|
||||
orderInfo.orderHash,
|
||||
makerSigner,
|
||||
order.maker
|
||||
).rrevert();
|
||||
}
|
||||
|
||||
// If msg.sender is not the taker, validate the taker signature.
|
||||
if (!_isSenderValidTaker(order.taker)) {
|
||||
address takerSigner = LibSignature.getSignerOfHash(orderInfo.orderHash, takerSignature);
|
||||
if (
|
||||
takerSigner != order.taker &&
|
||||
!stor.orderSignerRegistry[order.taker][takerSigner]
|
||||
) {
|
||||
LibNativeOrdersRichErrors.OrderNotSignedByTakerError(
|
||||
orderInfo.orderHash,
|
||||
takerSigner,
|
||||
order.taker
|
||||
).rrevert();
|
||||
}
|
||||
taker = order.taker;
|
||||
}
|
||||
}
|
||||
|
||||
// Settle between the maker and taker.
|
||||
(takerTokenFilledAmount, makerTokenFilledAmount) = _settleOtcOrder(
|
||||
order,
|
||||
taker,
|
||||
takerTokenFillAmount,
|
||||
wethOptions
|
||||
);
|
||||
|
||||
emit OtcOrderFilled(
|
||||
orderInfo.orderHash,
|
||||
order.maker,
|
||||
taker,
|
||||
address(order.makerToken),
|
||||
address(order.takerToken),
|
||||
takerTokenFilledAmount,
|
||||
makerTokenFilledAmount
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Settle the trade between an OTC order's maker and taker.
|
||||
/// @param order The OTC order.
|
||||
/// @param takerTokenFillAmount Maximum taker token amount to fill this
|
||||
/// order with.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function _settleOtcOrder(
|
||||
LibNativeOrder.OtcOrder memory order,
|
||||
address taker,
|
||||
uint128 takerTokenFillAmount,
|
||||
WethOptions wethOptions
|
||||
)
|
||||
private
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount)
|
||||
{
|
||||
{
|
||||
// Unpack nonce fields
|
||||
uint64 nonceBucket = uint64(order.expiryAndNonce >> 128);
|
||||
uint128 nonce = uint128(order.expiryAndNonce);
|
||||
// Update tx origin nonce for the order
|
||||
LibOtcOrdersStorage.getStorage().txOriginNonces
|
||||
[order.txOrigin][nonceBucket] = nonce;
|
||||
}
|
||||
|
||||
if (takerTokenFillAmount == order.takerAmount) {
|
||||
takerTokenFilledAmount = order.takerAmount;
|
||||
makerTokenFilledAmount = order.makerAmount;
|
||||
} else {
|
||||
// Clamp the taker token fill amount to the fillable amount.
|
||||
takerTokenFilledAmount = LibSafeMathV06.min128(
|
||||
takerTokenFillAmount,
|
||||
order.takerAmount
|
||||
);
|
||||
// Compute the maker token amount.
|
||||
// This should never overflow because the values are all clamped to
|
||||
// (2^128-1).
|
||||
makerTokenFilledAmount = uint128(LibMathV06.getPartialAmountFloor(
|
||||
uint256(takerTokenFilledAmount),
|
||||
uint256(order.takerAmount),
|
||||
uint256(order.makerAmount)
|
||||
));
|
||||
}
|
||||
|
||||
if (wethOptions == WethOptions.WrapEth) {
|
||||
require(
|
||||
order.takerToken == WETH,
|
||||
"OtcOrdersFeature/INVALID_WRAP_ETH"
|
||||
);
|
||||
// Wrap ETH
|
||||
WETH.deposit{value: takerTokenFilledAmount}();
|
||||
// Transfer WETH to maker
|
||||
WETH.transfer(order.maker, takerTokenFilledAmount);
|
||||
if (takerTokenFilledAmount < msg.value) {
|
||||
// Refund unused ETH
|
||||
_transferEth(
|
||||
msg.sender,
|
||||
msg.value - uint256(takerTokenFilledAmount)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Transfer taker -> maker
|
||||
_transferERC20TokensFrom(
|
||||
order.takerToken,
|
||||
taker,
|
||||
order.maker,
|
||||
takerTokenFilledAmount
|
||||
);
|
||||
}
|
||||
|
||||
if (wethOptions == WethOptions.UnwrapWeth) {
|
||||
require(
|
||||
order.makerToken == WETH,
|
||||
"OtcOrdersFeature/INVALID_UNWRAP_WETH"
|
||||
);
|
||||
// Transfer maker tokens in
|
||||
_transferERC20TokensFrom(
|
||||
order.makerToken,
|
||||
order.maker,
|
||||
address(this),
|
||||
makerTokenFilledAmount
|
||||
);
|
||||
// Unwrap WETH
|
||||
WETH.withdraw(makerTokenFilledAmount);
|
||||
// Transfer ETH to taker
|
||||
_transferEth(taker, makerTokenFilledAmount);
|
||||
} else {
|
||||
// Transfer maker -> taker.
|
||||
_transferERC20TokensFrom(
|
||||
order.makerToken,
|
||||
order.maker,
|
||||
taker,
|
||||
makerTokenFilledAmount
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Get the order info for an OTC order.
|
||||
/// @param order The OTC order.
|
||||
/// @return orderInfo Info about the order.
|
||||
function getOtcOrderInfo(LibNativeOrder.OtcOrder memory order)
|
||||
public
|
||||
override
|
||||
view
|
||||
returns (LibNativeOrder.OtcOrderInfo memory orderInfo)
|
||||
{
|
||||
// compute order hash.
|
||||
orderInfo.orderHash = getOtcOrderHash(order);
|
||||
|
||||
LibOtcOrdersStorage.Storage storage stor =
|
||||
LibOtcOrdersStorage.getStorage();
|
||||
|
||||
// Unpack expiry and nonce fields
|
||||
uint64 expiry = uint64(order.expiryAndNonce >> 192);
|
||||
uint64 nonceBucket = uint64(order.expiryAndNonce >> 128);
|
||||
uint128 nonce = uint128(order.expiryAndNonce);
|
||||
|
||||
// check tx origin nonce
|
||||
uint128 lastNonce = stor.txOriginNonces
|
||||
[order.txOrigin]
|
||||
[nonceBucket];
|
||||
if (nonce <= lastNonce) {
|
||||
orderInfo.status = LibNativeOrder.OrderStatus.INVALID;
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
// Check for expiration.
|
||||
if (expiry <= uint64(block.timestamp)) {
|
||||
orderInfo.status = LibNativeOrder.OrderStatus.EXPIRED;
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
orderInfo.status = LibNativeOrder.OrderStatus.FILLABLE;
|
||||
return orderInfo;
|
||||
}
|
||||
|
||||
/// @dev Get the canonical hash of an OTC order.
|
||||
/// @param order The OTC order.
|
||||
/// @return orderHash The order hash.
|
||||
function getOtcOrderHash(LibNativeOrder.OtcOrder memory order)
|
||||
public
|
||||
override
|
||||
view
|
||||
returns (bytes32 orderHash)
|
||||
{
|
||||
return _getEIP712Hash(
|
||||
LibNativeOrder.getOtcOrderStructHash(order)
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Get the last nonce used for a particular
|
||||
/// tx.origin address and nonce bucket.
|
||||
/// @param txOrigin The address.
|
||||
/// @param nonceBucket The nonce bucket index.
|
||||
/// @return lastNonce The last nonce value used.
|
||||
function lastOtcTxOriginNonce(address txOrigin, uint64 nonceBucket)
|
||||
public
|
||||
override
|
||||
view
|
||||
returns (uint128 lastNonce)
|
||||
{
|
||||
LibOtcOrdersStorage.Storage storage stor =
|
||||
LibOtcOrdersStorage.getStorage();
|
||||
return stor.txOriginNonces
|
||||
[txOrigin]
|
||||
[nonceBucket];
|
||||
}
|
||||
|
||||
function _transferEth(address recipient, uint256 amount)
|
||||
private
|
||||
{
|
||||
// Transfer ETH to recipient
|
||||
(bool success, bytes memory revertData) =
|
||||
recipient.call{value: amount}("");
|
||||
// Revert on failure
|
||||
if (!success) {
|
||||
revertData.rrevert();
|
||||
}
|
||||
}
|
||||
|
||||
function _isSenderValidTaker(address orderTaker)
|
||||
private
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return orderTaker == address(0) || orderTaker == msg.sender;
|
||||
}
|
||||
}
|
@@ -312,7 +312,7 @@ contract TransformERC20Feature is
|
||||
// Transfer input tokens.
|
||||
if (!LibERC20Transformer.isTokenETH(inputToken) && amount != 0) {
|
||||
// Token is not ETH, so pull ERC20 tokens.
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
inputToken,
|
||||
from,
|
||||
to,
|
||||
|
419
contracts/zero-ex/contracts/src/features/UniswapV3Feature.sol
Normal file
419
contracts/zero-ex/contracts/src/features/UniswapV3Feature.sol
Normal file
@@ -0,0 +1,419 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2021 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "../vendor/IUniswapV3Pool.sol";
|
||||
import "../migrations/LibMigrate.sol";
|
||||
import "../fixins/FixinCommon.sol";
|
||||
import "../fixins/FixinTokenSpender.sol";
|
||||
import "./interfaces/IFeature.sol";
|
||||
import "./interfaces/IUniswapV3Feature.sol";
|
||||
|
||||
|
||||
/// @dev VIP uniswap fill functions.
|
||||
contract UniswapV3Feature is
|
||||
IFeature,
|
||||
IUniswapV3Feature,
|
||||
FixinCommon,
|
||||
FixinTokenSpender
|
||||
{
|
||||
/// @dev Name of this feature.
|
||||
string public constant override FEATURE_NAME = "UniswapV3Feature";
|
||||
/// @dev Version of this feature.
|
||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
||||
/// @dev WETH contract.
|
||||
IEtherTokenV06 private immutable WETH;
|
||||
/// @dev UniswapV3 Factory contract address prepended with '0xff' and left-aligned.
|
||||
bytes32 private immutable UNI_FF_FACTORY_ADDRESS;
|
||||
/// @dev UniswapV3 pool init code hash.
|
||||
bytes32 private immutable UNI_POOL_INIT_CODE_HASH;
|
||||
/// @dev Minimum size of an encoded swap path:
|
||||
/// sizeof(address(inputToken) | uint24(fee) | address(outputToken))
|
||||
uint256 private constant SINGLE_HOP_PATH_SIZE = 20 + 3 + 20;
|
||||
/// @dev How many bytes to skip ahead in an encoded path to start at the next hop:
|
||||
/// sizeof(address(inputToken) | uint24(fee))
|
||||
uint256 private constant PATH_SKIP_HOP_SIZE = 20 + 3;
|
||||
/// @dev The size of the swap callback data.
|
||||
uint256 private constant SWAP_CALLBACK_DATA_SIZE = 128;
|
||||
/// @dev Minimum tick price sqrt ratio.
|
||||
uint160 internal constant MIN_PRICE_SQRT_RATIO = 4295128739;
|
||||
/// @dev Minimum tick price sqrt ratio.
|
||||
uint160 internal constant MAX_PRICE_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
|
||||
/// @dev Mask of lower 20 bytes.
|
||||
uint256 private constant ADDRESS_MASK = 0x00ffffffffffffffffffffffffffffffffffffffff;
|
||||
/// @dev Mask of lower 3 bytes.
|
||||
uint256 private constant UINT24_MASK = 0xffffff;
|
||||
|
||||
/// @dev Construct this contract.
|
||||
/// @param weth The WETH contract.
|
||||
/// @param uniFactory The UniswapV3 factory contract.
|
||||
/// @param poolInitCodeHash The UniswapV3 pool init code hash.
|
||||
constructor(
|
||||
IEtherTokenV06 weth,
|
||||
address uniFactory,
|
||||
bytes32 poolInitCodeHash
|
||||
) public {
|
||||
WETH = weth;
|
||||
UNI_FF_FACTORY_ADDRESS = bytes32((uint256(0xff) << 248) | (uint256(uniFactory) << 88));
|
||||
UNI_POOL_INIT_CODE_HASH = poolInitCodeHash;
|
||||
}
|
||||
|
||||
/// @dev Initialize and register this feature.
|
||||
/// Should be delegatecalled by `Migrate.migrate()`.
|
||||
/// @return success `LibMigrate.SUCCESS` on success.
|
||||
function migrate()
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
_registerFeatureFunction(this.sellEthForTokenToUniswapV3.selector);
|
||||
_registerFeatureFunction(this.sellTokenForEthToUniswapV3.selector);
|
||||
_registerFeatureFunction(this.sellTokenForTokenToUniswapV3.selector);
|
||||
_registerFeatureFunction(this.uniswapV3SwapCallback.selector);
|
||||
return LibMigrate.MIGRATE_SUCCESS;
|
||||
}
|
||||
|
||||
/// @dev Sell attached ETH directly against uniswap v3.
|
||||
/// @param encodedPath Uniswap-encoded path, where the first token is WETH.
|
||||
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
|
||||
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
|
||||
/// @return buyAmount Amount of the last token in the path bought.
|
||||
function sellEthForTokenToUniswapV3(
|
||||
bytes memory encodedPath,
|
||||
uint256 minBuyAmount,
|
||||
address recipient
|
||||
)
|
||||
public
|
||||
payable
|
||||
override
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
// Wrap ETH.
|
||||
WETH.deposit{ value: msg.value }();
|
||||
return _swap(
|
||||
encodedPath,
|
||||
msg.value,
|
||||
minBuyAmount,
|
||||
address(this), // we are payer because we hold the WETH
|
||||
_normalizeRecipient(recipient)
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Sell a token for ETH directly against uniswap v3.
|
||||
/// @param encodedPath Uniswap-encoded path, where the last token is WETH.
|
||||
/// @param sellAmount amount of the first token in the path to sell.
|
||||
/// @param minBuyAmount Minimum amount of ETH to buy.
|
||||
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
|
||||
/// @return buyAmount Amount of ETH bought.
|
||||
function sellTokenForEthToUniswapV3(
|
||||
bytes memory encodedPath,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
address payable recipient
|
||||
)
|
||||
public
|
||||
override
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
buyAmount = _swap(
|
||||
encodedPath,
|
||||
sellAmount,
|
||||
minBuyAmount,
|
||||
msg.sender,
|
||||
address(this) // we are recipient because we need to unwrap WETH
|
||||
);
|
||||
WETH.withdraw(buyAmount);
|
||||
// Transfer ETH to recipient.
|
||||
(bool success, bytes memory revertData) =
|
||||
_normalizeRecipient(recipient).call{ value: buyAmount }("");
|
||||
if (!success) {
|
||||
revertData.rrevert();
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sell a token for another token directly against uniswap v3.
|
||||
/// @param encodedPath Uniswap-encoded path.
|
||||
/// @param sellAmount amount of the first token in the path to sell.
|
||||
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
|
||||
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
|
||||
/// @return buyAmount Amount of the last token in the path bought.
|
||||
function sellTokenForTokenToUniswapV3(
|
||||
bytes memory encodedPath,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
address recipient
|
||||
)
|
||||
public
|
||||
override
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
buyAmount = _swap(
|
||||
encodedPath,
|
||||
sellAmount,
|
||||
minBuyAmount,
|
||||
msg.sender,
|
||||
_normalizeRecipient(recipient)
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev The UniswapV3 pool swap callback which pays the funds requested
|
||||
/// by the caller/pool to the pool. Can only be called by a valid
|
||||
/// UniswapV3 pool.
|
||||
/// @param amount0Delta Token0 amount owed.
|
||||
/// @param amount1Delta Token1 amount owed.
|
||||
/// @param data Arbitrary data forwarded from swap() caller. An ABI-encoded
|
||||
/// struct of: inputToken, outputToken, fee, payer
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
bytes calldata data
|
||||
)
|
||||
external
|
||||
override
|
||||
{
|
||||
IERC20TokenV06 token0;
|
||||
IERC20TokenV06 token1;
|
||||
address payer;
|
||||
{
|
||||
uint24 fee;
|
||||
// Decode the data.
|
||||
require(data.length == SWAP_CALLBACK_DATA_SIZE, "UniswapFeature/INVALID_SWAP_CALLBACK_DATA");
|
||||
assembly {
|
||||
let p := add(36, calldataload(68))
|
||||
token0 := calldataload(p)
|
||||
token1 := calldataload(add(p, 32))
|
||||
fee := calldataload(add(p, 64))
|
||||
payer := calldataload(add(p, 96))
|
||||
}
|
||||
(token0, token1) = token0 < token1
|
||||
? (token0, token1)
|
||||
: (token1, token0);
|
||||
// Only a valid pool contract can call this function.
|
||||
require(
|
||||
msg.sender == address(_toPool(token0, fee, token1)),
|
||||
"UniswapV3Feature/INVALID_SWAP_CALLBACK_CALLER"
|
||||
);
|
||||
}
|
||||
// Pay the amount owed to the pool.
|
||||
if (amount0Delta > 0) {
|
||||
_pay(token0, payer, msg.sender, uint256(amount0Delta));
|
||||
} else if (amount1Delta > 0) {
|
||||
_pay(token1, payer, msg.sender, uint256(amount1Delta));
|
||||
} else {
|
||||
revert("UniswapV3Feature/INVALID_SWAP_AMOUNTS");
|
||||
}
|
||||
}
|
||||
|
||||
// Executes successive swaps along an encoded uniswap path.
|
||||
function _swap(
|
||||
bytes memory encodedPath,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
address payer,
|
||||
address recipient
|
||||
)
|
||||
private
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
if (sellAmount != 0) {
|
||||
require(sellAmount <= uint256(type(int256).max), "UniswapV3Feature/SELL_AMOUNT_OVERFLOW");
|
||||
|
||||
// Perform a swap for each hop in the path.
|
||||
bytes memory swapCallbackData = new bytes(SWAP_CALLBACK_DATA_SIZE);
|
||||
while (true) {
|
||||
bool isPathMultiHop = _isPathMultiHop(encodedPath);
|
||||
bool zeroForOne;
|
||||
IUniswapV3Pool pool;
|
||||
{
|
||||
(
|
||||
IERC20TokenV06 inputToken,
|
||||
uint24 fee,
|
||||
IERC20TokenV06 outputToken
|
||||
) = _decodeFirstPoolInfoFromPath(encodedPath);
|
||||
pool = _toPool(inputToken, fee, outputToken);
|
||||
zeroForOne = inputToken < outputToken;
|
||||
_updateSwapCallbackData(
|
||||
swapCallbackData,
|
||||
inputToken,
|
||||
outputToken,
|
||||
fee,
|
||||
payer
|
||||
);
|
||||
}
|
||||
(int256 amount0, int256 amount1) = pool.swap(
|
||||
// Intermediate tokens go to this contract.
|
||||
isPathMultiHop ? address(this) : recipient,
|
||||
zeroForOne,
|
||||
int256(sellAmount),
|
||||
zeroForOne
|
||||
? MIN_PRICE_SQRT_RATIO + 1
|
||||
: MAX_PRICE_SQRT_RATIO - 1,
|
||||
swapCallbackData
|
||||
);
|
||||
{
|
||||
int256 _buyAmount = -(zeroForOne ? amount1 : amount0);
|
||||
require(_buyAmount >= 0, "UniswapV3Feature/INVALID_BUY_AMOUNT");
|
||||
buyAmount = uint256(_buyAmount);
|
||||
}
|
||||
if (!isPathMultiHop) {
|
||||
// Done.
|
||||
break;
|
||||
}
|
||||
// Continue with next hop.
|
||||
payer = address(this); // Subsequent hops are paid for by us.
|
||||
sellAmount = buyAmount;
|
||||
// Skip to next hop along path.
|
||||
encodedPath = _shiftHopFromPathInPlace(encodedPath);
|
||||
}
|
||||
}
|
||||
require(minBuyAmount <= buyAmount, "UniswapV3Feature/UNDERBOUGHT");
|
||||
}
|
||||
|
||||
// Pay tokens from `payer` to `to`, using `transferFrom()` if
|
||||
// `payer` != this contract.
|
||||
function _pay(
|
||||
IERC20TokenV06 token,
|
||||
address payer,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
private
|
||||
{
|
||||
if (payer != address(this)) {
|
||||
_transferERC20TokensFrom(token, payer, to, amount);
|
||||
} else {
|
||||
_transferERC20Tokens(token, to, amount);
|
||||
}
|
||||
}
|
||||
|
||||
// Update `swapCallbackData` in place with new values.
|
||||
function _updateSwapCallbackData(
|
||||
bytes memory swapCallbackData,
|
||||
IERC20TokenV06 inputToken,
|
||||
IERC20TokenV06 outputToken,
|
||||
uint24 fee,
|
||||
address payer
|
||||
)
|
||||
private
|
||||
pure
|
||||
{
|
||||
assembly {
|
||||
let p := add(swapCallbackData, 32)
|
||||
mstore(p, inputToken)
|
||||
mstore(add(p, 32), outputToken)
|
||||
mstore(add(p, 64), and(UINT24_MASK, fee))
|
||||
mstore(add(p, 96), and(ADDRESS_MASK, payer))
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the pool address given two tokens and a fee.
|
||||
function _toPool(
|
||||
IERC20TokenV06 inputToken,
|
||||
uint24 fee,
|
||||
IERC20TokenV06 outputToken
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (IUniswapV3Pool pool)
|
||||
{
|
||||
// address(keccak256(abi.encodePacked(
|
||||
// hex"ff",
|
||||
// UNI_FACTORY_ADDRESS,
|
||||
// keccak256(abi.encode(inputToken, outputToken, fee)),
|
||||
// UNI_POOL_INIT_CODE_HASH
|
||||
// )))
|
||||
bytes32 ffFactoryAddress = UNI_FF_FACTORY_ADDRESS;
|
||||
bytes32 poolInitCodeHash = UNI_POOL_INIT_CODE_HASH;
|
||||
(IERC20TokenV06 token0, IERC20TokenV06 token1) = inputToken < outputToken
|
||||
? (inputToken, outputToken)
|
||||
: (outputToken, inputToken);
|
||||
assembly {
|
||||
let s := mload(0x40)
|
||||
let p := s
|
||||
mstore(p, ffFactoryAddress)
|
||||
p := add(p, 21)
|
||||
// Compute the inner hash in-place
|
||||
mstore(p, token0)
|
||||
mstore(add(p, 32), token1)
|
||||
mstore(add(p, 64), and(UINT24_MASK, fee))
|
||||
mstore(p, keccak256(p, 96))
|
||||
p := add(p, 32)
|
||||
mstore(p, poolInitCodeHash)
|
||||
pool := and(ADDRESS_MASK, keccak256(s, 85))
|
||||
}
|
||||
}
|
||||
|
||||
// Return whether or not an encoded uniswap path contains more than one hop.
|
||||
function _isPathMultiHop(bytes memory encodedPath)
|
||||
private
|
||||
pure
|
||||
returns (bool isMultiHop)
|
||||
{
|
||||
return encodedPath.length > SINGLE_HOP_PATH_SIZE;
|
||||
}
|
||||
|
||||
|
||||
// Return the first input token, output token, and fee of an encoded uniswap path.
|
||||
function _decodeFirstPoolInfoFromPath(bytes memory encodedPath)
|
||||
private
|
||||
pure
|
||||
returns (
|
||||
IERC20TokenV06 inputToken,
|
||||
uint24 fee,
|
||||
IERC20TokenV06 outputToken
|
||||
)
|
||||
{
|
||||
require(encodedPath.length >= SINGLE_HOP_PATH_SIZE, "UniswapV3Feature/BAD_PATH_ENCODING");
|
||||
assembly {
|
||||
let p := add(encodedPath, 32)
|
||||
inputToken := shr(96, mload(p))
|
||||
p := add(p, 20)
|
||||
fee := shr(232, mload(p))
|
||||
p := add(p, 3)
|
||||
outputToken := shr(96, mload(p))
|
||||
}
|
||||
}
|
||||
|
||||
// Skip past the first hop of an encoded uniswap path in-place.
|
||||
function _shiftHopFromPathInPlace(bytes memory encodedPath)
|
||||
private
|
||||
pure
|
||||
returns (bytes memory shiftedEncodedPath)
|
||||
{
|
||||
require(encodedPath.length >= PATH_SKIP_HOP_SIZE, "UniswapV3Feature/BAD_PATH_ENCODING");
|
||||
uint256 shiftSize = PATH_SKIP_HOP_SIZE;
|
||||
uint256 newSize = encodedPath.length - shiftSize;
|
||||
assembly {
|
||||
shiftedEncodedPath := add(encodedPath, shiftSize)
|
||||
mstore(shiftedEncodedPath, newSize)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert null address values to msg.sender.
|
||||
function _normalizeRecipient(address recipient)
|
||||
private
|
||||
view
|
||||
returns (address payable normalizedRecipient)
|
||||
{
|
||||
return recipient == address(0) ? msg.sender : payable(recipient);
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2021 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "../libs/LibNativeOrder.sol";
|
||||
import "../libs/LibSignature.sol";
|
||||
|
||||
|
||||
/// @dev Feature for interacting with OTC orders.
|
||||
interface IOtcOrdersFeature {
|
||||
|
||||
/// @dev Emitted whenever an `OtcOrder` is filled.
|
||||
/// @param orderHash The canonical hash of the order.
|
||||
/// @param maker The maker of the order.
|
||||
/// @param taker The taker of the order.
|
||||
/// @param takerTokenFilledAmount How much taker token was filled.
|
||||
/// @param makerTokenFilledAmount How much maker token was filled.
|
||||
event OtcOrderFilled(
|
||||
bytes32 orderHash,
|
||||
address maker,
|
||||
address taker,
|
||||
address makerToken,
|
||||
address takerToken,
|
||||
uint128 takerTokenFilledAmount,
|
||||
uint128 makerTokenFilledAmount
|
||||
);
|
||||
|
||||
/// @dev Fill an OTC order for up to `takerTokenFillAmount` taker tokens.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @param takerTokenFillAmount Maximum taker token amount to fill this
|
||||
/// order with.
|
||||
/// @param unwrapWeth Whether or not to unwrap bought WETH into ETH
|
||||
/// before transferring it to the taker. Should be set to false
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function fillOtcOrder(
|
||||
LibNativeOrder.OtcOrder calldata order,
|
||||
LibSignature.Signature calldata makerSignature,
|
||||
uint128 takerTokenFillAmount,
|
||||
bool unwrapWeth
|
||||
)
|
||||
external
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Fill an OTC order whose taker token is WETH for up
|
||||
/// to `msg.value`.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function fillOtcOrderWithEth(
|
||||
LibNativeOrder.OtcOrder calldata order,
|
||||
LibSignature.Signature calldata makerSignature
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Fully fill an OTC order. "Meta-transaction" variant,
|
||||
/// requires order to be signed by both maker and taker.
|
||||
/// @param order The OTC order.
|
||||
/// @param makerSignature The order signature from the maker.
|
||||
/// @param takerSignature The order signature from the taker.
|
||||
/// @param unwrapWeth Whether or not to unwrap bought WETH into ETH
|
||||
/// before transferring it to the taker. Should be set to false
|
||||
/// if the maker token is not WETH.
|
||||
/// @return takerTokenFilledAmount How much taker token was filled.
|
||||
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||
function fillTakerSignedOtcOrder(
|
||||
LibNativeOrder.OtcOrder calldata order,
|
||||
LibSignature.Signature calldata makerSignature,
|
||||
LibSignature.Signature calldata takerSignature,
|
||||
bool unwrapWeth
|
||||
)
|
||||
external
|
||||
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||
|
||||
/// @dev Get the order info for an OTC order.
|
||||
/// @param order The OTC order.
|
||||
/// @return orderInfo Info about the order.
|
||||
function getOtcOrderInfo(LibNativeOrder.OtcOrder calldata order)
|
||||
external
|
||||
view
|
||||
returns (LibNativeOrder.OtcOrderInfo memory orderInfo);
|
||||
|
||||
/// @dev Get the canonical hash of an OTC order.
|
||||
/// @param order The OTC order.
|
||||
/// @return orderHash The order hash.
|
||||
function getOtcOrderHash(LibNativeOrder.OtcOrder calldata order)
|
||||
external
|
||||
view
|
||||
returns (bytes32 orderHash);
|
||||
|
||||
/// @dev Get the last nonce used for a particular
|
||||
/// tx.origin address and nonce bucket.
|
||||
/// @param txOrigin The address.
|
||||
/// @param nonceBucket The nonce bucket index.
|
||||
/// @return lastNonce The last nonce value used.
|
||||
function lastOtcTxOriginNonce(address txOrigin, uint64 nonceBucket)
|
||||
external
|
||||
view
|
||||
returns (uint128 lastNonce);
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
|
||||
|
||||
/// @dev VIP uniswap v3 fill functions.
|
||||
interface IUniswapV3Feature {
|
||||
|
||||
/// @dev Sell attached ETH directly against uniswap v3.
|
||||
/// @param encodedPath Uniswap-encoded path, where the first token is WETH.
|
||||
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
|
||||
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
|
||||
/// @return buyAmount Amount of the last token in the path bought.
|
||||
function sellEthForTokenToUniswapV3(
|
||||
bytes memory encodedPath,
|
||||
uint256 minBuyAmount,
|
||||
address recipient
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (uint256 buyAmount);
|
||||
|
||||
/// @dev Sell a token for ETH directly against uniswap v3.
|
||||
/// @param encodedPath Uniswap-encoded path, where the last token is WETH.
|
||||
/// @param sellAmount amount of the first token in the path to sell.
|
||||
/// @param minBuyAmount Minimum amount of ETH to buy.
|
||||
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
|
||||
/// @return buyAmount Amount of ETH bought.
|
||||
function sellTokenForEthToUniswapV3(
|
||||
bytes memory encodedPath,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
address payable recipient
|
||||
)
|
||||
external
|
||||
returns (uint256 buyAmount);
|
||||
|
||||
/// @dev Sell a token for another token directly against uniswap v3.
|
||||
/// @param encodedPath Uniswap-encoded path.
|
||||
/// @param sellAmount amount of the first token in the path to sell.
|
||||
/// @param minBuyAmount Minimum amount of the last token in the path to buy.
|
||||
/// @param recipient The recipient of the bought tokens. Can be zero for sender.
|
||||
/// @return buyAmount Amount of the last token in the path bought.
|
||||
function sellTokenForTokenToUniswapV3(
|
||||
bytes memory encodedPath,
|
||||
uint256 sellAmount,
|
||||
uint256 minBuyAmount,
|
||||
address recipient
|
||||
)
|
||||
external
|
||||
returns (uint256 buyAmount);
|
||||
|
||||
/// @dev The UniswapV3 pool swap callback which pays the funds requested
|
||||
/// by the caller/pool to the pool. Can only be called by a valid
|
||||
/// UniswapV3 pool.
|
||||
/// @param amount0Delta Token0 amount owed.
|
||||
/// @param amount1Delta Token1 amount owed.
|
||||
/// @param data Arbitrary data forwarded from swap() caller. An ABI-encoded
|
||||
/// struct of: inputToken, outputToken, fee, payer
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
bytes calldata data
|
||||
)
|
||||
external;
|
||||
}
|
@@ -69,6 +69,18 @@ library LibNativeOrder {
|
||||
uint256 salt;
|
||||
}
|
||||
|
||||
/// @dev An OTC limit order.
|
||||
struct OtcOrder {
|
||||
IERC20TokenV06 makerToken;
|
||||
IERC20TokenV06 takerToken;
|
||||
uint128 makerAmount;
|
||||
uint128 takerAmount;
|
||||
address maker;
|
||||
address taker;
|
||||
address txOrigin;
|
||||
uint256 expiryAndNonce; // [uint64 expiry, uint64 nonceBucket, uint128 nonce]
|
||||
}
|
||||
|
||||
/// @dev Info on a limit or RFQ order.
|
||||
struct OrderInfo {
|
||||
bytes32 orderHash;
|
||||
@@ -76,6 +88,12 @@ library LibNativeOrder {
|
||||
uint128 takerTokenFilledAmount;
|
||||
}
|
||||
|
||||
/// @dev Info on an OTC order.
|
||||
struct OtcOrderInfo {
|
||||
bytes32 orderHash;
|
||||
OrderStatus status;
|
||||
}
|
||||
|
||||
uint256 private constant UINT_128_MASK = (1 << 128) - 1;
|
||||
uint256 private constant UINT_64_MASK = (1 << 64) - 1;
|
||||
uint256 private constant ADDRESS_MASK = (1 << 160) - 1;
|
||||
@@ -118,6 +136,22 @@ library LibNativeOrder {
|
||||
uint256 private constant _RFQ_ORDER_TYPEHASH =
|
||||
0xe593d3fdfa8b60e5e17a1b2204662ecbe15c23f2084b9ad5bae40359540a7da9;
|
||||
|
||||
// The type hash for OTC orders, which is:
|
||||
// keccak256(abi.encodePacked(
|
||||
// "OtcOrder(",
|
||||
// "address makerToken,",
|
||||
// "address takerToken,",
|
||||
// "uint128 makerAmount,",
|
||||
// "uint128 takerAmount,",
|
||||
// "address maker,",
|
||||
// "address taker,",
|
||||
// "address txOrigin,",
|
||||
// "uint256 expiryAndNonce"
|
||||
// ")"
|
||||
// ))
|
||||
uint256 private constant _OTC_ORDER_TYPEHASH =
|
||||
0x2f754524de756ae72459efbe1ec88c19a745639821de528ac3fb88f9e65e35c8;
|
||||
|
||||
/// @dev Get the struct hash of a limit order.
|
||||
/// @param order The limit order.
|
||||
/// @return structHash The struct hash of the order.
|
||||
@@ -222,6 +256,49 @@ library LibNativeOrder {
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Get the struct hash of an OTC order.
|
||||
/// @param order The OTC order.
|
||||
/// @return structHash The struct hash of the order.
|
||||
function getOtcOrderStructHash(OtcOrder memory order)
|
||||
internal
|
||||
pure
|
||||
returns (bytes32 structHash)
|
||||
{
|
||||
// The struct hash is:
|
||||
// keccak256(abi.encode(
|
||||
// TYPE_HASH,
|
||||
// order.makerToken,
|
||||
// order.takerToken,
|
||||
// order.makerAmount,
|
||||
// order.takerAmount,
|
||||
// order.maker,
|
||||
// order.taker,
|
||||
// order.txOrigin,
|
||||
// order.expiryAndNonce,
|
||||
// ))
|
||||
assembly {
|
||||
let mem := mload(0x40)
|
||||
mstore(mem, _OTC_ORDER_TYPEHASH)
|
||||
// order.makerToken;
|
||||
mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order)))
|
||||
// order.takerToken;
|
||||
mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20))))
|
||||
// order.makerAmount;
|
||||
mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40))))
|
||||
// order.takerAmount;
|
||||
mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
|
||||
// order.maker;
|
||||
mstore(add(mem, 0xA0), and(ADDRESS_MASK, mload(add(order, 0x80))))
|
||||
// order.taker;
|
||||
mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
|
||||
// order.txOrigin;
|
||||
mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
|
||||
// order.expiryAndNonce;
|
||||
mstore(add(mem, 0x100), mload(add(order, 0xE0)))
|
||||
structHash := keccak256(mem, 0x120)
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Refund any leftover protocol fees in `msg.value` to `msg.sender`.
|
||||
/// @param ethProtocolFeePaid How much ETH was paid in protocol fees.
|
||||
function refundExcessProtocolFeeToSender(uint256 ethProtocolFeePaid)
|
||||
|
@@ -404,7 +404,7 @@ abstract contract NativeOrdersSettlement is
|
||||
params.order.takerAmount,
|
||||
params.order.takerTokenFeeAmount
|
||||
));
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
params.order.takerToken,
|
||||
params.taker,
|
||||
params.order.feeRecipient,
|
||||
@@ -550,7 +550,7 @@ abstract contract NativeOrdersSettlement is
|
||||
settleInfo.takerTokenFilledAmount.safeAdd128(takerTokenFilledAmount);
|
||||
|
||||
// Transfer taker -> maker.
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
settleInfo.takerToken,
|
||||
settleInfo.taker,
|
||||
settleInfo.maker,
|
||||
@@ -558,7 +558,7 @@ abstract contract NativeOrdersSettlement is
|
||||
);
|
||||
|
||||
// Transfer maker -> taker.
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
settleInfo.makerToken,
|
||||
settleInfo.maker,
|
||||
settleInfo.taker,
|
||||
|
@@ -35,7 +35,7 @@ abstract contract FixinTokenSpender {
|
||||
/// @param owner The owner of the tokens.
|
||||
/// @param to The recipient of the tokens.
|
||||
/// @param amount The amount of `token` to transfer.
|
||||
function _transferERC20Tokens(
|
||||
function _transferERC20TokensFrom(
|
||||
IERC20TokenV06 token,
|
||||
address owner,
|
||||
address to,
|
||||
@@ -87,6 +87,60 @@ abstract contract FixinTokenSpender {
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Transfers ERC20 tokens from ourselves to `to`.
|
||||
/// @param token The token to spend.
|
||||
/// @param to The recipient of the tokens.
|
||||
/// @param amount The amount of `token` to transfer.
|
||||
function _transferERC20Tokens(
|
||||
IERC20TokenV06 token,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
require(address(token) != address(this), "FixinTokenSpender/CANNOT_INVOKE_SELF");
|
||||
|
||||
assembly {
|
||||
let ptr := mload(0x40) // free memory pointer
|
||||
|
||||
// selector for transfer(address,uint256)
|
||||
mstore(ptr, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
|
||||
mstore(add(ptr, 0x04), and(to, ADDRESS_MASK))
|
||||
mstore(add(ptr, 0x24), amount)
|
||||
|
||||
let success := call(
|
||||
gas(),
|
||||
and(token, ADDRESS_MASK),
|
||||
0,
|
||||
ptr,
|
||||
0x44,
|
||||
ptr,
|
||||
32
|
||||
)
|
||||
|
||||
let rdsize := returndatasize()
|
||||
|
||||
// Check for ERC20 success. ERC20 tokens should return a boolean,
|
||||
// but some don't. We accept 0-length return data as success, or at
|
||||
// least 32 bytes that starts with a 32-byte boolean true.
|
||||
success := and(
|
||||
success, // call itself succeeded
|
||||
or(
|
||||
iszero(rdsize), // no return data, or
|
||||
and(
|
||||
iszero(lt(rdsize, 32)), // at least 32 bytes
|
||||
eq(mload(ptr), 1) // starts with uint256(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if iszero(success) {
|
||||
returndatacopy(ptr, 0, rdsize)
|
||||
revert(ptr, rdsize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Gets the maximum amount of an ERC20 token `token` that can be
|
||||
/// pulled from `owner` by this address.
|
||||
/// @param token The token to spend.
|
||||
|
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./LibStorage.sol";
|
||||
|
||||
|
||||
/// @dev Storage helpers for `OtcOrdersFeature`.
|
||||
library LibOtcOrdersStorage {
|
||||
|
||||
/// @dev Storage bucket for this feature.
|
||||
struct Storage {
|
||||
// tx origin => nonce buckets => min nonce
|
||||
mapping(address => mapping(uint64 => uint128)) txOriginNonces;
|
||||
}
|
||||
|
||||
/// @dev Get the storage bucket for this contract.
|
||||
function getStorage() internal pure returns (Storage storage stor) {
|
||||
uint256 storageSlot = LibStorage.getStorageSlot(
|
||||
LibStorage.StorageId.OtcOrders
|
||||
);
|
||||
// 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 }
|
||||
}
|
||||
}
|
@@ -38,7 +38,8 @@ library LibStorage {
|
||||
TransformERC20,
|
||||
MetaTransactions,
|
||||
ReentrancyGuard,
|
||||
NativeOrders
|
||||
NativeOrders,
|
||||
OtcOrders
|
||||
}
|
||||
|
||||
/// @dev Get the storage slot given a storage ID. We assign unique, well-spaced
|
||||
|
@@ -27,10 +27,12 @@ import "./mixins/MixinBalancerV2.sol";
|
||||
import "./mixins/MixinBancor.sol";
|
||||
import "./mixins/MixinCoFiX.sol";
|
||||
import "./mixins/MixinCurve.sol";
|
||||
import "./mixins/MixinCurveV2.sol";
|
||||
import "./mixins/MixinCryptoCom.sol";
|
||||
import "./mixins/MixinDodo.sol";
|
||||
import "./mixins/MixinDodoV2.sol";
|
||||
import "./mixins/MixinKyber.sol";
|
||||
import "./mixins/MixinKyberDmm.sol";
|
||||
import "./mixins/MixinMakerPSM.sol";
|
||||
import "./mixins/MixinMooniswap.sol";
|
||||
import "./mixins/MixinMStable.sol";
|
||||
@@ -49,10 +51,12 @@ contract BridgeAdapter is
|
||||
MixinBancor,
|
||||
MixinCoFiX,
|
||||
MixinCurve,
|
||||
MixinCurveV2,
|
||||
MixinCryptoCom,
|
||||
MixinDodo,
|
||||
MixinDodoV2,
|
||||
MixinKyber,
|
||||
MixinKyberDmm,
|
||||
MixinMakerPSM,
|
||||
MixinMooniswap,
|
||||
MixinMStable,
|
||||
@@ -71,6 +75,7 @@ contract BridgeAdapter is
|
||||
MixinBancor(weth)
|
||||
MixinCoFiX()
|
||||
MixinCurve(weth)
|
||||
MixinCurveV2()
|
||||
MixinCryptoCom()
|
||||
MixinDodo()
|
||||
MixinDodoV2()
|
||||
@@ -105,6 +110,13 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.CURVEV2) {
|
||||
boughtAmount = _tradeCurveV2(
|
||||
sellToken,
|
||||
buyToken,
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.UNISWAPV3) {
|
||||
boughtAmount = _tradeUniswapV3(
|
||||
sellToken,
|
||||
@@ -217,6 +229,12 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.KYBERDMM) {
|
||||
boughtAmount = _tradeKyberDmm(
|
||||
buyToken,
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else {
|
||||
boughtAmount = _tradeZeroExBridge(
|
||||
sellToken,
|
||||
|
@@ -46,4 +46,6 @@ library BridgeProtocols {
|
||||
uint128 internal constant MAKERPSM = 16;
|
||||
uint128 internal constant BALANCERV2 = 17;
|
||||
uint128 internal constant UNISWAPV3 = 18;
|
||||
uint128 internal constant KYBERDMM = 19;
|
||||
uint128 internal constant CURVEV2 = 20;
|
||||
}
|
||||
|
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2020 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
|
||||
contract MixinCurveV2 {
|
||||
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
using LibSafeMathV06 for uint256;
|
||||
using LibRichErrorsV06 for bytes;
|
||||
|
||||
struct CurveBridgeDataV2 {
|
||||
address curveAddress;
|
||||
bytes4 exchangeFunctionSelector;
|
||||
int128 fromCoinIdx;
|
||||
int128 toCoinIdx;
|
||||
}
|
||||
|
||||
function _tradeCurveV2(
|
||||
IERC20TokenV06 sellToken,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
// Decode the bridge data to get the Curve metadata.
|
||||
CurveBridgeDataV2 memory data = abi.decode(bridgeData, (CurveBridgeDataV2));
|
||||
sellToken.approveIfBelow(data.curveAddress, sellAmount);
|
||||
|
||||
uint256 beforeBalance = buyToken.balanceOf(address(this));
|
||||
(bool success, bytes memory resultData) =
|
||||
data.curveAddress.call(abi.encodeWithSelector(
|
||||
data.exchangeFunctionSelector,
|
||||
data.fromCoinIdx,
|
||||
data.toCoinIdx,
|
||||
// dx
|
||||
sellAmount,
|
||||
// min dy
|
||||
1
|
||||
));
|
||||
if (!success) {
|
||||
resultData.rrevert();
|
||||
}
|
||||
|
||||
return buyToken.balanceOf(address(this)).safeSub(beforeBalance);
|
||||
}
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*
|
||||
|
||||
Copyright 2021 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "../IBridgeAdapter.sol";
|
||||
|
||||
/*
|
||||
KyberDmm Router
|
||||
*/
|
||||
interface IKyberDmmRouter {
|
||||
|
||||
/// @dev Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path.
|
||||
/// The first element of path is the input token, the last is the output token, and any intermediate elements represent
|
||||
/// intermediate pairs to trade through (if, for example, a direct pair does not exist).
|
||||
/// @param amountIn The amount of input tokens to send.
|
||||
/// @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert.
|
||||
/// @param pools An array of pool addresses. pools.length must be >= 1.
|
||||
/// @param path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity.
|
||||
/// @param to Recipient of the output tokens.
|
||||
/// @param deadline Unix timestamp after which the transaction will revert.
|
||||
/// @return amounts The input token amount and all subsequent output token amounts.
|
||||
function swapExactTokensForTokens(
|
||||
uint amountIn,
|
||||
uint amountOutMin,
|
||||
address[] calldata pools,
|
||||
address[] calldata path,
|
||||
address to,
|
||||
uint deadline
|
||||
) external returns (uint[] memory amounts);
|
||||
}
|
||||
|
||||
contract MixinKyberDmm {
|
||||
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
function _tradeKyberDmm(
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
address router;
|
||||
address[] memory pools;
|
||||
address[] memory path;
|
||||
(router, pools, path) = abi.decode(bridgeData, (address, address[], address[]));
|
||||
|
||||
require(pools.length >= 1, "MixinKyberDmm/POOLS_LENGTH_MUST_BE_AT_LEAST_ONE");
|
||||
require(path.length == pools.length + 1, "MixinKyberDmm/ARRAY_LENGTH_MISMATCH");
|
||||
require(
|
||||
path[path.length - 1] == address(buyToken),
|
||||
"MixinKyberDmm/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
|
||||
);
|
||||
// Grant the KyberDmm router an allowance to sell the first token.
|
||||
IERC20TokenV06(path[0]).approveIfBelow(address(router), sellAmount);
|
||||
|
||||
uint[] memory amounts = IKyberDmmRouter(router).swapExactTokensForTokens(
|
||||
// Sell all tokens we hold.
|
||||
sellAmount,
|
||||
// Minimum buy amount.
|
||||
1,
|
||||
pools,
|
||||
// Convert to `buyToken` along this path.
|
||||
path,
|
||||
// Recipient is `this`.
|
||||
address(this),
|
||||
// Expires after this block.
|
||||
block.timestamp
|
||||
);
|
||||
return amounts[amounts.length-1];
|
||||
}
|
||||
}
|
@@ -31,6 +31,7 @@ interface IMStable {
|
||||
IERC20TokenV06 sellToken,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
uint256 minBoughtAmount,
|
||||
address recipient
|
||||
)
|
||||
external
|
||||
@@ -59,6 +60,8 @@ contract MixinMStable {
|
||||
sellToken,
|
||||
buyToken,
|
||||
sellAmount,
|
||||
// Minimum buy amount.
|
||||
1,
|
||||
address(this)
|
||||
);
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ contract MixinUniswapV2 {
|
||||
assembly { path := _path }
|
||||
}
|
||||
|
||||
require(path.length >= 2, "MixinUniswapV3/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
|
||||
require(path.length >= 2, "MixinUniswapV2/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
|
||||
require(
|
||||
path[path.length - 1] == buyToken,
|
||||
"MixinUniswapV2/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
|
||||
|
44
contracts/zero-ex/contracts/src/vendor/IUniswapV3Pool.sol
vendored
Normal file
44
contracts/zero-ex/contracts/src/vendor/IUniswapV3Pool.sol
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
|
||||
Copyright 2021 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.6.12;
|
||||
|
||||
|
||||
interface IUniswapV3Pool {
|
||||
|
||||
/// @notice Swap token0 for token1, or token1 for token0
|
||||
/// @dev The caller of this method receives a callback in the form of IUniswapV3SwapCallback#uniswapV3SwapCallback
|
||||
/// @param recipient The address to receive the output of the swap
|
||||
/// @param zeroForOne The direction of the swap, true for token0 to token1, false for token1 to token0
|
||||
/// @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)
|
||||
/// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this
|
||||
/// value after the swap. If one for zero, the price cannot be greater than this value after the swap
|
||||
/// @param data Any data to be passed through to the callback
|
||||
/// @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive
|
||||
/// @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive
|
||||
function swap(
|
||||
address recipient,
|
||||
bool zeroForOne,
|
||||
int256 amountSpecified,
|
||||
uint160 sqrtPriceLimitX96,
|
||||
bytes calldata data
|
||||
)
|
||||
external
|
||||
returns (int256 amount0, int256 amount1);
|
||||
}
|
@@ -28,7 +28,7 @@ contract TestFixinTokenSpender is
|
||||
{
|
||||
constructor() public {}
|
||||
|
||||
function transferERC20Tokens(
|
||||
function transferERC20TokensFrom(
|
||||
IERC20TokenV06 token,
|
||||
address owner,
|
||||
address to,
|
||||
@@ -36,7 +36,7 @@ contract TestFixinTokenSpender is
|
||||
)
|
||||
external
|
||||
{
|
||||
_transferERC20Tokens(
|
||||
_transferERC20TokensFrom(
|
||||
token,
|
||||
owner,
|
||||
to,
|
||||
|
4
contracts/zero-ex/contracts/test/TestNoEthRecipient.sol
Normal file
4
contracts/zero-ex/contracts/test/TestNoEthRecipient.sol
Normal file
@@ -0,0 +1,4 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.6;
|
||||
|
||||
contract TestNoEthRecipient {}
|
46
contracts/zero-ex/contracts/test/TestUniswapV3Factory.sol
Normal file
46
contracts/zero-ex/contracts/test/TestUniswapV3Factory.sol
Normal file
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "./TestUniswapV3Pool.sol";
|
||||
|
||||
contract TestUniswapV3Factory {
|
||||
struct CreationParameters {
|
||||
IERC20TokenV06 token0;
|
||||
IERC20TokenV06 token1;
|
||||
uint24 fee;
|
||||
}
|
||||
|
||||
event PoolCreated(TestUniswapV3Pool pool);
|
||||
|
||||
bytes32 public immutable POOL_INIT_CODE_HASH;
|
||||
mapping (IERC20TokenV06 => mapping (IERC20TokenV06 => mapping (uint24 => TestUniswapV3Pool))) public getPool;
|
||||
CreationParameters public creationParameters;
|
||||
|
||||
constructor() public {
|
||||
POOL_INIT_CODE_HASH = keccak256(type(TestUniswapV3Pool).creationCode);
|
||||
}
|
||||
|
||||
function createPool(IERC20TokenV06 tokenA, IERC20TokenV06 tokenB, uint24 fee)
|
||||
external
|
||||
returns (TestUniswapV3Pool pool)
|
||||
{
|
||||
(IERC20TokenV06 token0, IERC20TokenV06 token1) = tokenA < tokenB
|
||||
? (tokenA, tokenB)
|
||||
: (tokenB, tokenA);
|
||||
require(
|
||||
getPool[token0][token1][fee] == TestUniswapV3Pool(0),
|
||||
"TestUniswapV3Factory/POOL_ALREADY_EXISTS"
|
||||
);
|
||||
creationParameters = CreationParameters({
|
||||
token0: token0,
|
||||
token1: token1,
|
||||
fee: fee
|
||||
});
|
||||
pool = new TestUniswapV3Pool
|
||||
{ salt: keccak256(abi.encode(token0, token1, fee)) }();
|
||||
getPool[token0][token1][fee] = pool;
|
||||
getPool[token1][token0][fee] = pool;
|
||||
emit PoolCreated(pool);
|
||||
}
|
||||
}
|
17
contracts/zero-ex/contracts/test/TestUniswapV3Feature.sol
Normal file
17
contracts/zero-ex/contracts/test/TestUniswapV3Feature.sol
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import "../src/features/UniswapV3Feature.sol";
|
||||
|
||||
contract TestUniswapV3Feature is UniswapV3Feature {
|
||||
constructor(
|
||||
IEtherTokenV06 weth,
|
||||
address uniFactory,
|
||||
bytes32 poolInitCodeHash
|
||||
)
|
||||
UniswapV3Feature(weth, uniFactory, poolInitCodeHash)
|
||||
public
|
||||
{}
|
||||
|
||||
receive() external payable {}
|
||||
}
|
75
contracts/zero-ex/contracts/test/TestUniswapV3Pool.sol
Normal file
75
contracts/zero-ex/contracts/test/TestUniswapV3Pool.sol
Normal file
@@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "../src/vendor/IUniswapV3Pool.sol";
|
||||
|
||||
interface IUniswapV3PoolDeployer {
|
||||
struct CreationParameters {
|
||||
IERC20TokenV06 token0;
|
||||
IERC20TokenV06 token1;
|
||||
uint24 fee;
|
||||
}
|
||||
|
||||
function creationParameters() external view returns (CreationParameters memory);
|
||||
}
|
||||
|
||||
interface IUniswapV3SwapCallback {
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
bytes calldata data
|
||||
)
|
||||
external;
|
||||
}
|
||||
|
||||
contract TestUniswapV3Pool is IUniswapV3Pool {
|
||||
IERC20TokenV06 public immutable token0;
|
||||
IERC20TokenV06 public immutable token1;
|
||||
uint24 public immutable fee;
|
||||
|
||||
constructor() public {
|
||||
IUniswapV3PoolDeployer.CreationParameters memory params =
|
||||
IUniswapV3PoolDeployer(msg.sender).creationParameters();
|
||||
(token0, token1, fee) = (params.token0, params.token1, params.fee);
|
||||
}
|
||||
|
||||
function swap(
|
||||
address recipient,
|
||||
bool zeroForOne,
|
||||
int256 amountSpecified,
|
||||
uint160,
|
||||
bytes calldata data
|
||||
)
|
||||
external
|
||||
override
|
||||
returns (int256 amount0, int256 amount1)
|
||||
{
|
||||
uint256 balance0Before = token0.balanceOf(address(this));
|
||||
uint256 balance1Before = token1.balanceOf(address(this));
|
||||
if (zeroForOne) {
|
||||
amount0 = int256(amountSpecified);
|
||||
// Always buy 100% of other token balance.
|
||||
amount1 = -int256(balance1Before);
|
||||
token1.transfer(recipient, balance1Before);
|
||||
} else {
|
||||
amount0 = -int256(balance0Before);
|
||||
// Always buy 100% of other token balance.
|
||||
amount1 = int256(amountSpecified);
|
||||
token0.transfer(recipient, balance0Before);
|
||||
}
|
||||
IUniswapV3SwapCallback(msg.sender).uniswapV3SwapCallback(
|
||||
amount0,
|
||||
amount1,
|
||||
data
|
||||
);
|
||||
int256 balance0Change = int256(token0.balanceOf(address(this))) -
|
||||
int256(balance0Before);
|
||||
int256 balance1Change = int256(token1.balanceOf(address(this))) -
|
||||
int256(balance1Before);
|
||||
require(
|
||||
balance0Change >= amount0 && balance1Change >= amount1,
|
||||
"TestUniswapV3Pool/SWAP_NOT_PAID"
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user