Compare commits
252 Commits
@0x/dev-ut
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
490aafba4e | ||
|
3cd31d49bb | ||
|
6dd78b8d35 | ||
|
bd51c34098 | ||
|
0e758fadee | ||
|
a67659ff8e | ||
|
d1203f90da | ||
|
c5f6ebee18 | ||
|
41cc5234c4 | ||
|
c2d3e5f052 | ||
|
f944b95e32 | ||
|
0a5b919cd9 | ||
|
b5f85c11fe | ||
|
5d44b5e913 | ||
|
dd1961d86c | ||
|
f3539bf448 | ||
|
d831e559f0 | ||
|
cc079660f3 | ||
|
4460dac697 | ||
|
31190f921c | ||
|
22515d8dce | ||
|
a099d970a4 | ||
|
95bb2c5504 | ||
|
0b1262cc4d | ||
|
f9244f6f7e | ||
|
cfa1bf36de | ||
|
c362b33b5a | ||
|
222a151eff | ||
|
d6115cff25 | ||
|
6459522617 | ||
|
16e1f0eea1 | ||
|
0564ac1530 | ||
|
b896f82282 | ||
|
d737d419d9 | ||
|
0de2b6983b | ||
|
25628c34ee | ||
|
54fdccd397 | ||
|
27af4a988d | ||
|
fddad131a2 | ||
|
4d493eeebd | ||
|
14c1495a1a | ||
|
49c029ddb3 | ||
|
ddbe142c4c | ||
|
4710b40e45 | ||
|
be0b296769 | ||
|
0a0ee67740 | ||
|
943d648225 | ||
|
6d835f5cc1 | ||
|
a59cd67acf | ||
|
bbc06be091 | ||
|
d303e9f347 | ||
|
85ee923d89 | ||
|
fe6ba20ff5 | ||
|
18acf50b12 | ||
|
509fabb61c | ||
|
cc3378b4cd | ||
|
8d3ccf333d | ||
|
520919b165 | ||
|
600b86dd31 | ||
|
9c3fdd2584 | ||
|
73974cd90f | ||
|
8a60b3b402 | ||
|
59ed5ae6b7 | ||
|
c687385974 | ||
|
2f72e15ea7 | ||
|
7ea99baeb2 | ||
|
14f3d20772 | ||
|
72f51df25f | ||
|
a94b58e304 | ||
|
d327fabf9c | ||
|
9e02888c74 | ||
|
98c9a847f3 | ||
|
a159f4c9d6 | ||
|
b197731ed2 | ||
|
028f54fdf0 | ||
|
de62a0f8ed | ||
|
a0fcc50a5f | ||
|
4f186e843c | ||
|
df64c20587 | ||
|
c78a602990 | ||
|
0acec57ba9 | ||
|
7423028fea | ||
|
49d951b7be | ||
|
a554c9518d | ||
|
f3c7ba445e | ||
|
3abff41385 | ||
|
6c36832f0e | ||
|
310c18707b | ||
|
422a4a5578 | ||
|
a995b2e1ae | ||
|
90ad681a9e | ||
|
2ff5c39712 | ||
|
ded849fd6d | ||
|
02f7064953 | ||
|
1ddadfce1e | ||
|
7720e5007c | ||
|
ccfd021796 | ||
|
fdcad84cee | ||
|
ad3e3b8421 | ||
|
f67b4f8902 | ||
|
3c0d7319ba | ||
|
7f0aab6ec6 | ||
|
669578a926 | ||
|
fa1db64a8e | ||
|
7cf60fa927 | ||
|
75a0d3e494 | ||
|
a98218ae22 | ||
|
10952e9dc4 | ||
|
b36e23471b | ||
|
f45bf1c95b | ||
|
d4db2587aa | ||
|
62e6336a7d | ||
|
2d8acd4711 | ||
|
d7d95be042 | ||
|
e3c97f0681 | ||
|
1a4fa015b9 | ||
|
63dacfaac5 | ||
|
f7263ac2c6 | ||
|
c7d7e1f0e3 | ||
|
9c54b615f5 | ||
|
69fe1aa981 | ||
|
bfb3d19e3b | ||
|
0b4e62a63e | ||
|
5cdbc03e71 | ||
|
16cd6dd25d | ||
|
fc71e7f99f | ||
|
e740380731 | ||
|
f9921d2c91 | ||
|
d8bfc92cc5 | ||
|
1f2214f891 | ||
|
50835e317f | ||
|
6c8d4dcc1e | ||
|
85a7efbd61 | ||
|
6b5ef10467 | ||
|
0bf46bfcb5 | ||
|
8b8dc7ac78 | ||
|
a017122c44 | ||
|
86a9a892d2 | ||
|
f31a141d78 | ||
|
fa67997424 | ||
|
a5f06c577d | ||
|
e575672877 | ||
|
a34d5b29e8 | ||
|
91ec65da1b | ||
|
ee8d40a66e | ||
|
38ac2e80ed | ||
|
8b70762e34 | ||
|
18c613a611 | ||
|
957f8c56a1 | ||
|
b16446877e | ||
|
9164d58dc7 | ||
|
0beb2f9d3c | ||
|
ccdd66052a | ||
|
518fd814b6 | ||
|
f49bb78dba | ||
|
a54aa77d28 | ||
|
f85e443c9c | ||
|
399e004e7f | ||
|
3099ba71eb | ||
|
951fcf384c | ||
|
c750368a3e | ||
|
3149d86855 | ||
|
3aaf21e34e | ||
|
519c375a42 | ||
|
3ed2c732bd | ||
|
0aa5550d0f | ||
|
1bc8dd83d3 | ||
|
c642cd6fed | ||
|
f72918362d | ||
|
28c4ca73ab | ||
|
a256494ec8 | ||
|
5fd359a64f | ||
|
e043735362 | ||
|
7010b1adb9 | ||
|
17ff262729 | ||
|
1c18838cd8 | ||
|
55b87ae78d | ||
|
e446e902f3 | ||
|
095b52e0b2 | ||
|
4f25ff6a50 | ||
|
6242e0aeec | ||
|
fde9fc9dd4 | ||
|
c481e42673 | ||
|
5e228d7232 | ||
|
6b8e40fdc9 | ||
|
bca44bf9e3 | ||
|
08e49dcf2e | ||
|
0f45409b4d | ||
|
5469d3ec13 | ||
|
d12f8410b9 | ||
|
704c52d229 | ||
|
7dcdda14f5 | ||
|
0f59256ca7 | ||
|
ddee04e98c | ||
|
50f5002b71 | ||
|
e866add4b0 | ||
|
39b93b88c5 | ||
|
deb7e95567 | ||
|
91500501ce | ||
|
6a1caeb9a1 | ||
|
cee7803c37 | ||
|
4e8d0ac7cb | ||
|
47bbcb9935 | ||
|
c0288c5f26 | ||
|
18c2013625 | ||
|
548089888d | ||
|
180c65cfeb | ||
|
6a28e41bc8 | ||
|
f9ef942a98 | ||
|
8272c7a74e | ||
|
4e745489db | ||
|
fc2625a0c0 | ||
|
d0e43ebaf1 | ||
|
879805e316 | ||
|
6845d2e0ef | ||
|
542d1c1c41 | ||
|
31568e7abb | ||
|
4b2488b124 | ||
|
6ed1412bdd | ||
|
78b9a45158 | ||
|
b8925baa88 | ||
|
87fd3f2a82 | ||
|
8af164dbd2 | ||
|
c994afbf3c | ||
|
843caf86fb | ||
|
44eef5b0e0 | ||
|
346c6fc590 | ||
|
7ed3afe9f0 | ||
|
2fbe0aed32 | ||
|
3bdc1802cb | ||
|
849ca58228 | ||
|
9991fca2e5 | ||
|
9c7bdcfeef | ||
|
b5463d522b | ||
|
af0d830103 | ||
|
d4187dffa3 | ||
|
a7f06f2be5 | ||
|
7ff7d1a185 | ||
|
e3bc80e027 | ||
|
095882d016 | ||
|
1693506f80 | ||
|
9366fa3b45 | ||
|
d356e9e65f | ||
|
230ebffd0e | ||
|
5eedc1edca | ||
|
b88e42a52d | ||
|
8d1b27d130 | ||
|
1148d37102 | ||
|
88704ce417 | ||
|
9f69d2cb76 | ||
|
55fd71c5e1 | ||
|
1991bd437f |
@@ -11,9 +11,14 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
|
||||
- run:
|
||||
# HACK(albrow): Without this, yarn commands will sometimes
|
||||
# fail with a "permission denied" error.
|
||||
name: Set npm path
|
||||
command: npm set prefix=/home/circleci/npm && echo 'export PATH=$HOME/circleci/npm/bin:$PATH' >> /home/circleci/.bashrc
|
||||
- run:
|
||||
name: install-yarn
|
||||
command: sudo npm install --global yarn@1.9.4
|
||||
command: npm install --global yarn@1.9.4
|
||||
- run:
|
||||
name: yarn
|
||||
command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install
|
||||
@@ -119,6 +124,7 @@ jobs:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn wsrun test:circleci @0x/contracts-test-utils
|
||||
- run: yarn wsrun test:circleci @0x/abi-gen
|
||||
- run: yarn wsrun test:circleci @0x/contract-artifacts
|
||||
- run: yarn wsrun test:circleci @0x/assert
|
||||
- run: yarn wsrun test:circleci @0x/base-contract
|
||||
- run: yarn wsrun test:circleci @0x/connect
|
||||
@@ -201,8 +207,11 @@ jobs:
|
||||
- image: circleci/python
|
||||
- image: 0xorg/ganache-cli:2.2.2
|
||||
- image: 0xorg/launch-kit-ci
|
||||
command: |
|
||||
yarn start:ts -p 3000:3000
|
||||
environment:
|
||||
RPC_URL: http://localhost:8545
|
||||
NETWORK_ID: 50
|
||||
WHITELIST_ALL_TOKENS: True
|
||||
command: bash -c "until curl -sfd'{\"method\":\"net_listening\"}' http://localhost:8545 | grep true; do continue; done; forever ts/lib/index.js"
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo chown -R circleci:circleci /usr/local/bin
|
||||
@@ -390,9 +399,11 @@ workflows:
|
||||
- test-contracts-ganache:
|
||||
requires:
|
||||
- build
|
||||
- test-contracts-geth:
|
||||
requires:
|
||||
- build
|
||||
# TODO(albrow): Tests always fail on Geth right now because our fork
|
||||
# is outdated. Uncomment once we have updated our Geth fork.
|
||||
# - test-contracts-geth:
|
||||
# requires:
|
||||
# - build
|
||||
- test-pipeline:
|
||||
requires:
|
||||
- build
|
||||
|
@@ -1,4 +1,33 @@
|
||||
[
|
||||
{
|
||||
"version": "2.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Update tests to use contract-built-in `awaitTransactionSuccessAsync`",
|
||||
"pr": 1797
|
||||
}
|
||||
],
|
||||
"timestamp": 1557507213
|
||||
},
|
||||
{
|
||||
"version": "2.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.2 - _May 10, 2019_
|
||||
|
||||
* Update tests to use contract-built-in `awaitTransactionSuccessAsync` (#1797)
|
||||
|
||||
## v2.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v2.0.0 - _March 20, 2019_
|
||||
|
||||
* Do not reexport external dependencies (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
@@ -30,6 +30,7 @@
|
||||
"src/MultiAssetProxy.sol",
|
||||
"src/interfaces/IAssetData.sol",
|
||||
"src/interfaces/IAssetProxy.sol",
|
||||
"src/interfaces/IAuthorizable.sol"
|
||||
"src/interfaces/IAuthorizable.sol",
|
||||
"src/libs/LibAssetData.sol"
|
||||
]
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ contract ERC1155Proxy is
|
||||
{
|
||||
|
||||
// Id of this proxy.
|
||||
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC1155Token(address,uint256[],uint256[],bytes)"));
|
||||
bytes4 constant internal PROXY_ID = bytes4(keccak256("ERC1155Assets(address,uint256[],uint256[],bytes)"));
|
||||
|
||||
function ()
|
||||
external
|
||||
|
420
contracts/asset-proxy/contracts/src/libs/LibAssetData.sol
Normal file
420
contracts/asset-proxy/contracts/src/libs/LibAssetData.sol
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 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.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-erc1155/contracts/src/interfaces/IERC1155.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "@0x/contracts-erc721/contracts/src/interfaces/IERC721Token.sol";
|
||||
|
||||
|
||||
library LibAssetData {
|
||||
bytes4 constant public ERC20_PROXY_ID = bytes4(keccak256("ERC20Token(address)"));
|
||||
bytes4 constant public ERC721_PROXY_ID = bytes4(keccak256("ERC721Token(address,uint256)"));
|
||||
bytes4 constant public ERC1155_PROXY_ID = bytes4(keccak256("ERC1155Assets(address,uint256[],uint256[],bytes)"));
|
||||
bytes4 constant public MULTI_ASSET_PROXY_ID = bytes4(keccak256("MultiAsset(uint256[],bytes[])"));
|
||||
|
||||
/// @dev Returns the owner's balance of the token(s) specified in
|
||||
/// assetData. When the asset data contains multiple tokens (eg in
|
||||
/// ERC1155 or Multi-Asset), the return value indicates how many
|
||||
/// complete "baskets" of those tokens are owned by owner.
|
||||
/// @param owner Owner of the tokens specified by assetData.
|
||||
/// @param assetData Description of tokens, per the AssetProxy contract
|
||||
/// specification.
|
||||
/// @return Number of tokens (or token baskets) held by owner.
|
||||
function getBalance(address owner, bytes memory assetData)
|
||||
public
|
||||
view
|
||||
returns (uint256 balance)
|
||||
{
|
||||
bytes4 proxyId = LibBytes.readBytes4(assetData, 0);
|
||||
if (proxyId == ERC20_PROXY_ID) {
|
||||
address tokenAddress = LibBytes.readAddress(assetData, 16);
|
||||
return IERC20Token(tokenAddress).balanceOf(owner);
|
||||
} else if (proxyId == ERC721_PROXY_ID) {
|
||||
(, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData);
|
||||
return getERC721TokenOwner(tokenAddress, tokenId) == owner ? 1 : 0;
|
||||
} else if (proxyId == ERC1155_PROXY_ID) {
|
||||
uint256 lowestTokenBalance = 0;
|
||||
(
|
||||
,
|
||||
address tokenAddress,
|
||||
uint256[] memory tokenIds,
|
||||
uint256[] memory tokenValues,
|
||||
) = decodeERC1155AssetData(assetData);
|
||||
for (uint256 i = 0; i < tokenIds.length; i++) {
|
||||
uint256 tokenBalance = IERC1155(tokenAddress).balanceOf(owner, tokenIds[i]) / tokenValues[i];
|
||||
if (tokenBalance < lowestTokenBalance || lowestTokenBalance == 0) {
|
||||
lowestTokenBalance = tokenBalance;
|
||||
}
|
||||
}
|
||||
return lowestTokenBalance;
|
||||
} else if (proxyId == MULTI_ASSET_PROXY_ID) {
|
||||
uint256 lowestAssetBalance = 0;
|
||||
(, uint256[] memory assetAmounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
|
||||
for (uint256 i = 0; i < nestedAssetData.length; i++) {
|
||||
uint256 assetBalance = getBalance(owner, nestedAssetData[i]) / assetAmounts[i];
|
||||
if (assetBalance < lowestAssetBalance || lowestAssetBalance == 0) {
|
||||
lowestAssetBalance = assetBalance;
|
||||
}
|
||||
}
|
||||
return lowestAssetBalance;
|
||||
} else {
|
||||
revert("UNSUPPORTED_PROXY_IDENTIFIER");
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Calls getBalance() for each element of assetData.
|
||||
/// @param owner Owner of the tokens specified by assetData.
|
||||
/// @param assetData Array of token descriptors, each encoded per the
|
||||
/// AssetProxy contract specification.
|
||||
/// @return Array of token balances from getBalance(), with each element
|
||||
/// corresponding to the same-indexed element in the assetData input.
|
||||
function getBatchBalances(address owner, bytes[] memory assetData)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory balances)
|
||||
{
|
||||
balances = new uint256[](assetData.length);
|
||||
for (uint256 i = 0; i < assetData.length; i++) {
|
||||
balances[i] = getBalance(owner, assetData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Returns the number of token(s) (described by assetData) that
|
||||
/// spender is authorized to spend. When the asset data contains
|
||||
/// multiple tokens (eg for Multi-Asset), the return value indicates
|
||||
/// how many complete "baskets" of those tokens may be spent by spender.
|
||||
/// @param owner Owner of the tokens specified by assetData.
|
||||
/// @param spender Address whose authority to spend is in question.
|
||||
/// @param assetData Description of tokens, per the AssetProxy contract
|
||||
/// specification.
|
||||
/// @return Number of tokens (or token baskets) that the spender is
|
||||
/// authorized to spend.
|
||||
function getAllowance(address owner, address spender, bytes memory assetData)
|
||||
public
|
||||
view
|
||||
returns (uint256 allowance)
|
||||
{
|
||||
bytes4 proxyId = LibBytes.readBytes4(assetData, 0);
|
||||
|
||||
if (proxyId == ERC20_PROXY_ID) {
|
||||
address tokenAddress = LibBytes.readAddress(assetData, 16);
|
||||
return IERC20Token(tokenAddress).allowance(owner, spender);
|
||||
} else if (proxyId == ERC721_PROXY_ID) {
|
||||
(, address tokenAddress, uint256 tokenId) = decodeERC721AssetData(assetData);
|
||||
IERC721Token token = IERC721Token(tokenAddress);
|
||||
if (spender == token.getApproved(tokenId) || token.isApprovedForAll(owner, spender)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (proxyId == ERC1155_PROXY_ID) {
|
||||
(, address tokenAddress, , , ) = decodeERC1155AssetData(assetData);
|
||||
if (IERC1155(tokenAddress).isApprovedForAll(owner, spender)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (proxyId == MULTI_ASSET_PROXY_ID) {
|
||||
uint256 lowestAssetAllowance = 0;
|
||||
// solhint-disable-next-line indent
|
||||
(, uint256[] memory amounts, bytes[] memory nestedAssetData) = decodeMultiAssetData(assetData);
|
||||
for (uint256 i = 0; i < nestedAssetData.length; i++) {
|
||||
uint256 assetAllowance = getAllowance(owner, spender, nestedAssetData[i]) / amounts[i];
|
||||
if (assetAllowance < lowestAssetAllowance || lowestAssetAllowance == 0) {
|
||||
lowestAssetAllowance = assetAllowance;
|
||||
}
|
||||
}
|
||||
return lowestAssetAllowance;
|
||||
} else {
|
||||
revert("UNSUPPORTED_PROXY_IDENTIFIER");
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Calls getAllowance() for each element of assetData.
|
||||
/// @param owner Owner of the tokens specified by assetData.
|
||||
/// @param spender Address whose authority to spend is in question.
|
||||
/// @param assetData Description of tokens, per the AssetProxy contract
|
||||
/// specification.
|
||||
/// @return An array of token allowances from getAllowance(), with each
|
||||
/// element corresponding to the same-indexed element in the assetData
|
||||
/// input.
|
||||
function getBatchAllowances(address owner, address spender, bytes[] memory assetData)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory allowances)
|
||||
{
|
||||
allowances = new uint256[](assetData.length);
|
||||
for (uint256 i = 0; i < assetData.length; i++) {
|
||||
allowances[i] = getAllowance(owner, spender, assetData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Calls getBalance() and getAllowance() for assetData.
|
||||
/// @param owner Owner of the tokens specified by assetData.
|
||||
/// @param spender Address whose authority to spend is in question.
|
||||
/// @param assetData Description of tokens, per the AssetProxy contract
|
||||
/// specification.
|
||||
/// @return Number of tokens (or token baskets) held by owner, and number
|
||||
/// of tokens (or token baskets) that the spender is authorized to
|
||||
/// spend.
|
||||
function getBalanceAndAllowance(address owner, address spender, bytes memory assetData)
|
||||
public
|
||||
view
|
||||
returns (uint256 balance, uint256 allowance)
|
||||
{
|
||||
balance = getBalance(owner, assetData);
|
||||
allowance = getAllowance(owner, spender, assetData);
|
||||
}
|
||||
|
||||
/// @dev Calls getBatchBalances() and getBatchAllowances() for each element
|
||||
/// of assetData.
|
||||
/// @param owner Owner of the tokens specified by assetData.
|
||||
/// @param spender Address whose authority to spend is in question.
|
||||
/// @param assetData Description of tokens, per the AssetProxy contract
|
||||
/// specification.
|
||||
/// @return An array of token balances from getBalance(), and an array of
|
||||
/// token allowances from getAllowance(), with each element
|
||||
/// corresponding to the same-indexed element in the assetData input.
|
||||
function getBatchBalancesAndAllowances(address owner, address spender, bytes[] memory assetData)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory balances, uint256[] memory allowances)
|
||||
{
|
||||
balances = getBatchBalances(owner, assetData);
|
||||
allowances = getBatchAllowances(owner, spender, assetData);
|
||||
}
|
||||
|
||||
/// @dev Encode ERC-20 asset data into the format described in the
|
||||
/// AssetProxy contract specification.
|
||||
/// @param tokenAddress The address of the ERC-20 contract hosting the
|
||||
/// token to be traded.
|
||||
/// @return AssetProxy-compliant data describing the asset.
|
||||
function encodeERC20AssetData(address tokenAddress)
|
||||
public
|
||||
pure
|
||||
returns (bytes memory assetData)
|
||||
{
|
||||
return abi.encodeWithSelector(ERC20_PROXY_ID, tokenAddress);
|
||||
}
|
||||
|
||||
/// @dev Decode ERC-20 asset data from the format described in the
|
||||
/// AssetProxy contract specification.
|
||||
/// @param assetData AssetProxy-compliant asset data describing an ERC-20
|
||||
/// asset.
|
||||
/// @return The ERC-20 AssetProxy identifier, and the address of the ERC-20
|
||||
/// contract hosting this asset.
|
||||
function decodeERC20AssetData(bytes memory assetData)
|
||||
public
|
||||
pure
|
||||
returns (
|
||||
bytes4 proxyId,
|
||||
address tokenAddress
|
||||
)
|
||||
{
|
||||
proxyId = LibBytes.readBytes4(assetData, 0);
|
||||
|
||||
require(proxyId == ERC20_PROXY_ID, "WRONG_PROXY_ID");
|
||||
|
||||
tokenAddress = LibBytes.readAddress(assetData, 16);
|
||||
}
|
||||
|
||||
/// @dev Encode ERC-721 asset data into the format described in the
|
||||
/// AssetProxy specification.
|
||||
/// @param tokenAddress The address of the ERC-721 contract hosting the
|
||||
/// token to be traded.
|
||||
/// @param tokenId The identifier of the specific token to be traded.
|
||||
/// @return AssetProxy-compliant asset data describing the asset.
|
||||
function encodeERC721AssetData(
|
||||
address tokenAddress,
|
||||
uint256 tokenId
|
||||
)
|
||||
public
|
||||
pure
|
||||
returns (bytes memory assetData)
|
||||
{
|
||||
return abi.encodeWithSelector(ERC721_PROXY_ID, tokenAddress, tokenId);
|
||||
}
|
||||
|
||||
/// @dev Decode ERC-721 asset data from the format described in the
|
||||
/// AssetProxy contract specification.
|
||||
/// @param assetData AssetProxy-compliant asset data describing an ERC-721
|
||||
/// asset.
|
||||
/// @return The ERC-721 AssetProxy identifier, the address of the ERC-721
|
||||
/// contract hosting this asset, and the identifier of the specific
|
||||
/// token to be traded.
|
||||
function decodeERC721AssetData(bytes memory assetData)
|
||||
public
|
||||
pure
|
||||
returns (
|
||||
bytes4 proxyId,
|
||||
address tokenAddress,
|
||||
uint256 tokenId
|
||||
)
|
||||
{
|
||||
proxyId = LibBytes.readBytes4(assetData, 0);
|
||||
|
||||
require(proxyId == ERC721_PROXY_ID, "WRONG_PROXY_ID");
|
||||
|
||||
tokenAddress = LibBytes.readAddress(assetData, 16);
|
||||
tokenId = LibBytes.readUint256(assetData, 36);
|
||||
}
|
||||
|
||||
/// @dev Encode ERC-1155 asset data into the format described in the
|
||||
/// AssetProxy contract specification.
|
||||
/// @param tokenAddress The address of the ERC-1155 contract hosting the
|
||||
/// token(s) to be traded.
|
||||
/// @param tokenIds The identifiers of the specific tokens to be traded.
|
||||
/// @param tokenValues The amounts of each token to be traded.
|
||||
/// @param callbackData ...
|
||||
/// @return AssetProxy-compliant asset data describing the set of assets.
|
||||
function encodeERC1155AssetData(
|
||||
address tokenAddress,
|
||||
uint256[] memory tokenIds,
|
||||
uint256[] memory tokenValues,
|
||||
bytes memory callbackData
|
||||
)
|
||||
public
|
||||
pure
|
||||
returns (bytes memory assetData)
|
||||
{
|
||||
return abi.encodeWithSelector(ERC1155_PROXY_ID, tokenAddress, tokenIds, tokenValues, callbackData);
|
||||
}
|
||||
|
||||
/// @dev Decode ERC-1155 asset data from the format described in the
|
||||
/// AssetProxy contract specification.
|
||||
/// @param assetData AssetProxy-compliant asset data describing an ERC-1155
|
||||
/// set of assets.
|
||||
/// @return The ERC-1155 AssetProxy identifier, the address of the ERC-1155
|
||||
/// contract hosting the assets, an array of the identifiers of the
|
||||
/// tokens to be traded, an array of token amounts to be traded, and
|
||||
/// callback data. Each element of the arrays corresponds to the
|
||||
/// same-indexed element of the other array. Return values specified as
|
||||
/// `memory` are returned as pointers to locations within the memory of
|
||||
/// the input parameter `assetData`.
|
||||
function decodeERC1155AssetData(bytes memory assetData)
|
||||
public
|
||||
pure
|
||||
returns (
|
||||
bytes4 proxyId,
|
||||
address tokenAddress,
|
||||
uint256[] memory tokenIds,
|
||||
uint256[] memory tokenValues,
|
||||
bytes memory callbackData
|
||||
)
|
||||
{
|
||||
proxyId = LibBytes.readBytes4(assetData, 0);
|
||||
|
||||
require(proxyId == ERC1155_PROXY_ID, "WRONG_PROXY_ID");
|
||||
|
||||
assembly {
|
||||
// Skip selector and length to get to the first parameter:
|
||||
assetData := add(assetData, 36)
|
||||
// Read the value of the first parameter:
|
||||
tokenAddress := mload(assetData)
|
||||
// Point to the next parameter's data:
|
||||
tokenIds := add(assetData, mload(add(assetData, 32)))
|
||||
// Point to the next parameter's data:
|
||||
tokenValues := add(assetData, mload(add(assetData, 64)))
|
||||
// Point to the next parameter's data:
|
||||
callbackData := add(assetData, mload(add(assetData, 96)))
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Encode data for multiple assets, per the AssetProxy contract
|
||||
/// specification.
|
||||
/// @param amounts The amounts of each asset to be traded.
|
||||
/// @param nestedAssetData AssetProxy-compliant data describing each asset
|
||||
/// to be traded.
|
||||
/// @return AssetProxy-compliant data describing the set of assets.
|
||||
function encodeMultiAssetData(uint256[] memory amounts, bytes[] memory nestedAssetData)
|
||||
public
|
||||
pure
|
||||
returns (bytes memory assetData)
|
||||
{
|
||||
assetData = abi.encodeWithSelector(MULTI_ASSET_PROXY_ID, amounts, nestedAssetData);
|
||||
}
|
||||
|
||||
/// @dev Decode multi-asset data from the format described in the
|
||||
/// AssetProxy contract specification.
|
||||
/// @param assetData AssetProxy-compliant data describing a multi-asset
|
||||
/// basket.
|
||||
/// @return The Multi-Asset AssetProxy identifier, an array of the amounts
|
||||
/// of the assets to be traded, and an array of the
|
||||
/// AssetProxy-compliant data describing each asset to be traded. Each
|
||||
/// element of the arrays corresponds to the same-indexed element of
|
||||
/// the other array.
|
||||
function decodeMultiAssetData(bytes memory assetData)
|
||||
public
|
||||
pure
|
||||
returns (
|
||||
bytes4 proxyId,
|
||||
uint256[] memory amounts,
|
||||
bytes[] memory nestedAssetData
|
||||
)
|
||||
{
|
||||
proxyId = LibBytes.readBytes4(assetData, 0);
|
||||
|
||||
require(proxyId == MULTI_ASSET_PROXY_ID, "WRONG_PROXY_ID");
|
||||
|
||||
// solhint-disable-next-line indent
|
||||
(amounts, nestedAssetData) = abi.decode(LibBytes.slice(assetData, 4, assetData.length), (uint256[], bytes[]));
|
||||
}
|
||||
|
||||
/// @dev Calls `token.ownerOf(tokenId)`, but returns a null owner instead of reverting on an unowned token.
|
||||
/// @param token Address of ERC721 token.
|
||||
/// @param tokenId The identifier for the specific NFT.
|
||||
/// @return Owner of tokenId or null address if unowned.
|
||||
function getERC721TokenOwner(address token, uint256 tokenId)
|
||||
public
|
||||
view
|
||||
returns (address owner)
|
||||
{
|
||||
assembly {
|
||||
// load free memory pointer
|
||||
let cdStart := mload(64)
|
||||
|
||||
// bytes4(keccak256(ownerOf(uint256))) = 0x6352211e
|
||||
mstore(cdStart, 0x6352211e00000000000000000000000000000000000000000000000000000000)
|
||||
mstore(add(cdStart, 4), tokenId)
|
||||
|
||||
// staticcall `ownerOf(tokenId)`
|
||||
// `ownerOf` will revert if tokenId is not owned
|
||||
let success := staticcall(
|
||||
gas, // forward all gas
|
||||
token, // call token contract
|
||||
cdStart, // start of calldata
|
||||
36, // length of input is 36 bytes
|
||||
cdStart, // write output over input
|
||||
32 // size of output is 32 bytes
|
||||
)
|
||||
|
||||
// Success implies that tokenId is owned
|
||||
// Copy owner from return data if successful
|
||||
if success {
|
||||
owner := mload(cdStart)
|
||||
}
|
||||
}
|
||||
|
||||
// Owner initialized to address(0), no need to modify if call is unsuccessful
|
||||
return owner;
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-asset-proxy",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -33,7 +34,7 @@
|
||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|MixinAuthorizable|MultiAssetProxy).json",
|
||||
"abis": "./generated-artifacts/@(ERC1155Proxy|ERC20Proxy|ERC721Proxy|IAssetData|IAssetProxy|IAuthorizable|LibAssetData|MixinAuthorizable|MultiAssetProxy).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,17 +68,17 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-erc1155": "^1.0.1",
|
||||
"@0x/contracts-erc20": "^2.0.0",
|
||||
"@0x/contracts-erc721": "^2.0.0",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/order-utils": "^7.1.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-erc1155": "^1.1.2",
|
||||
"@0x/contracts-erc20": "^2.2.1",
|
||||
"@0x/contracts-erc721": "^2.1.2",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/order-utils": "^8.0.0",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -11,12 +11,14 @@ import * as ERC721Proxy from '../generated-artifacts/ERC721Proxy.json';
|
||||
import * as IAssetData from '../generated-artifacts/IAssetData.json';
|
||||
import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json';
|
||||
import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json';
|
||||
import * as LibAssetData from '../generated-artifacts/LibAssetData.json';
|
||||
import * as MixinAuthorizable from '../generated-artifacts/MixinAuthorizable.json';
|
||||
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
|
||||
export const artifacts = {
|
||||
LibAssetData: LibAssetData as ContractArtifact,
|
||||
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
|
||||
ERC20Proxy: ERC20Proxy as ContractArtifact,
|
||||
ERC721Proxy: ERC721Proxy as ContractArtifact,
|
||||
ERC1155Proxy: ERC1155Proxy as ContractArtifact,
|
||||
MixinAuthorizable: MixinAuthorizable as ContractArtifact,
|
||||
MultiAssetProxy: MultiAssetProxy as ContractArtifact,
|
||||
IAssetData: IAssetData as ContractArtifact,
|
||||
|
@@ -9,5 +9,6 @@ export * from '../generated-wrappers/erc721_proxy';
|
||||
export * from '../generated-wrappers/i_asset_data';
|
||||
export * from '../generated-wrappers/i_asset_proxy';
|
||||
export * from '../generated-wrappers/i_authorizable';
|
||||
export * from '../generated-wrappers/lib_asset_data';
|
||||
export * from '../generated-wrappers/mixin_authorizable';
|
||||
export * from '../generated-wrappers/multi_asset_proxy';
|
||||
|
@@ -53,16 +53,18 @@ describe('Authorizable', () => {
|
||||
);
|
||||
});
|
||||
it('should allow owner to add an authorized address', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isAuthorized = await authorizable.authorized.callAsync(address);
|
||||
expect(isAuthorized).to.be.true();
|
||||
});
|
||||
it('should throw if owner attempts to authorize a duplicate address', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
return expectTransactionFailedAsync(
|
||||
@@ -74,8 +76,9 @@ describe('Authorizable', () => {
|
||||
|
||||
describe('removeAuthorizedAddress', () => {
|
||||
it('should throw if not called by owner', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
return expectTransactionFailedAsync(
|
||||
@@ -87,14 +90,14 @@ describe('Authorizable', () => {
|
||||
});
|
||||
|
||||
it('should allow owner to remove an authorized address', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
||||
from: owner,
|
||||
}),
|
||||
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isAuthorized = await authorizable.authorized.callAsync(address);
|
||||
@@ -113,8 +116,9 @@ describe('Authorizable', () => {
|
||||
|
||||
describe('removeAuthorizedAddressAtIndex', () => {
|
||||
it('should throw if not called by owner', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const index = new BigNumber(0);
|
||||
@@ -126,8 +130,9 @@ describe('Authorizable', () => {
|
||||
);
|
||||
});
|
||||
it('should throw if index is >= authorities.length', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const index = new BigNumber(1);
|
||||
@@ -150,12 +155,14 @@ describe('Authorizable', () => {
|
||||
it('should throw if address at index does not match target', async () => {
|
||||
const address1 = address;
|
||||
const address2 = notOwner;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address1, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address1,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address2, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address2,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const address1Index = new BigNumber(0);
|
||||
@@ -167,15 +174,16 @@ describe('Authorizable', () => {
|
||||
);
|
||||
});
|
||||
it('should allow owner to remove an authorized address', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const index = new BigNumber(0);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, {
|
||||
from: owner,
|
||||
}),
|
||||
await authorizable.removeAuthorizedAddressAtIndex.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
index,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isAuthorized = await authorizable.authorized.callAsync(address);
|
||||
@@ -187,20 +195,17 @@ describe('Authorizable', () => {
|
||||
it('should return all authorized addresses', async () => {
|
||||
const initial = await authorizable.getAuthorizedAddresses.callAsync();
|
||||
expect(initial).to.have.length(0);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.addAuthorizedAddress.sendTransactionAsync(address, {
|
||||
from: owner,
|
||||
}),
|
||||
await authorizable.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const afterAdd = await authorizable.getAuthorizedAddresses.callAsync();
|
||||
expect(afterAdd).to.have.length(1);
|
||||
expect(afterAdd).to.include(address);
|
||||
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await authorizable.removeAuthorizedAddress.sendTransactionAsync(address, {
|
||||
from: owner,
|
||||
}),
|
||||
await authorizable.removeAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const afterRemove = await authorizable.getAuthorizedAddresses.callAsync();
|
||||
|
@@ -15,7 +15,7 @@ import {
|
||||
web3Wrapper,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||
import { RevertReason } from '@0x/types';
|
||||
import { AssetProxyId, RevertReason } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
@@ -70,16 +70,14 @@ describe('ERC1155Proxy', () => {
|
||||
const usedAddresses = ([owner, notAuthorized, authorized, spender, receiver] = _.slice(accounts, 0, 5));
|
||||
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
|
||||
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
authorized,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(erc1155Proxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
erc1155Proxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// deploy & configure ERC1155 tokens and receiver
|
||||
@@ -123,8 +121,7 @@ describe('ERC1155Proxy', () => {
|
||||
});
|
||||
it('should have an id of 0x9645780d', async () => {
|
||||
const proxyId = await erc1155Proxy.getProxyId.callAsync();
|
||||
// proxy computed using -- bytes4(keccak256("erc1155Token(address,uint256[],uint256[],bytes)"));
|
||||
const expectedProxyId = '0x9645780d';
|
||||
const expectedProxyId = AssetProxyId.ERC1155;
|
||||
expect(proxyId).to.equal(expectedProxyId);
|
||||
});
|
||||
});
|
||||
@@ -597,8 +594,8 @@ describe('ERC1155Proxy', () => {
|
||||
it('should propagate revert reason from erc1155 contract failure', async () => {
|
||||
// disable transfers
|
||||
const shouldRejectTransfer = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Receiver.setRejectTransferFlag.sendTransactionAsync(shouldRejectTransfer),
|
||||
await erc1155Receiver.setRejectTransferFlag.awaitTransactionSuccessAsync(
|
||||
shouldRejectTransfer,
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// setup test parameters
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
426
contracts/asset-proxy/test/lib_asset_data.ts
Normal file
426
contracts/asset-proxy/test/lib_asset_data.ts
Normal file
@@ -0,0 +1,426 @@
|
||||
// TODO: change test titles to say "... from asset data"
|
||||
import * as chai from 'chai';
|
||||
import { LogWithDecodedArgs } from 'ethereum-types';
|
||||
|
||||
import {
|
||||
artifacts as erc1155Artifacts,
|
||||
ERC1155MintableContract,
|
||||
ERC1155TransferSingleEventArgs,
|
||||
IERC1155MintableContract,
|
||||
} from '@0x/contracts-erc1155';
|
||||
import { artifacts as erc20Artifacts, DummyERC20TokenContract, IERC20TokenContract } from '@0x/contracts-erc20';
|
||||
import { artifacts as erc721Artifacts, DummyERC721TokenContract, IERC721TokenContract } from '@0x/contracts-erc721';
|
||||
import { chaiSetup, constants, LogDecoder, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
|
||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||
import { AssetProxyId } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { artifacts, LibAssetDataContract } from '../src';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
const KNOWN_ERC20_ENCODING = {
|
||||
address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
|
||||
assetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48',
|
||||
};
|
||||
const KNOWN_ERC721_ENCODING = {
|
||||
address: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
|
||||
tokenId: new BigNumber(1),
|
||||
assetData:
|
||||
'0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001',
|
||||
};
|
||||
const KNOWN_ERC1155_ENCODING = {
|
||||
tokenAddress: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
|
||||
tokenIds: [new BigNumber(100), new BigNumber(1001), new BigNumber(10001)],
|
||||
tokenValues: [new BigNumber(200), new BigNumber(2001), new BigNumber(20001)],
|
||||
callbackData:
|
||||
'0x025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001',
|
||||
assetData:
|
||||
'0xa7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000',
|
||||
};
|
||||
const KNOWN_MULTI_ASSET_ENCODING = {
|
||||
amounts: [new BigNumber(70), new BigNumber(1), new BigNumber(18)],
|
||||
nestedAssetData: [
|
||||
KNOWN_ERC20_ENCODING.assetData,
|
||||
KNOWN_ERC721_ENCODING.assetData,
|
||||
KNOWN_ERC1155_ENCODING.assetData,
|
||||
],
|
||||
assetData:
|
||||
'0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204a7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
||||
};
|
||||
|
||||
describe('LibAssetData', () => {
|
||||
let libAssetData: LibAssetDataContract;
|
||||
|
||||
let tokenOwnerAddress: string;
|
||||
let approvedSpenderAddress: string;
|
||||
let anotherApprovedSpenderAddress: string;
|
||||
|
||||
let erc20TokenAddress: string;
|
||||
const erc20TokenTotalSupply = new BigNumber(1);
|
||||
|
||||
let erc721TokenAddress: string;
|
||||
const firstERC721TokenId = new BigNumber(1);
|
||||
const numberOfERC721Tokens = 10;
|
||||
|
||||
let erc1155MintableAddress: string;
|
||||
let erc1155TokenId: BigNumber;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
|
||||
libAssetData = await LibAssetDataContract.deployFrom0xArtifactAsync(
|
||||
artifacts.LibAssetData,
|
||||
provider,
|
||||
txDefaults,
|
||||
);
|
||||
|
||||
[
|
||||
tokenOwnerAddress,
|
||||
approvedSpenderAddress,
|
||||
anotherApprovedSpenderAddress,
|
||||
] = await web3Wrapper.getAvailableAddressesAsync();
|
||||
|
||||
erc20TokenAddress = (await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
erc20Artifacts.DummyERC20Token,
|
||||
provider,
|
||||
txDefaults,
|
||||
'Dummy',
|
||||
'DUM',
|
||||
new BigNumber(1),
|
||||
erc20TokenTotalSupply,
|
||||
)).address;
|
||||
|
||||
const erc721TokenContract = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
|
||||
erc721Artifacts.DummyERC721Token,
|
||||
provider,
|
||||
txDefaults,
|
||||
'Dummy',
|
||||
'DUM',
|
||||
);
|
||||
erc721TokenAddress = erc721TokenContract.address;
|
||||
// mint `numberOfERC721Tokens` tokens
|
||||
const transactionMinedPromises = [];
|
||||
for (let i = 0; i < numberOfERC721Tokens; i++) {
|
||||
transactionMinedPromises.push(
|
||||
web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721TokenContract.mint.sendTransactionAsync(
|
||||
tokenOwnerAddress,
|
||||
firstERC721TokenId.plus(i - 1),
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
),
|
||||
);
|
||||
}
|
||||
await Promise.all(transactionMinedPromises);
|
||||
|
||||
const erc1155MintableContract = await ERC1155MintableContract.deployFrom0xArtifactAsync(
|
||||
erc1155Artifacts.ERC1155Mintable,
|
||||
provider,
|
||||
txDefaults,
|
||||
);
|
||||
erc1155MintableAddress = erc1155MintableContract.address;
|
||||
// Somewhat re-inventing the wheel here, but the prior art currently
|
||||
// exists only as an unexported test util in the erc1155 package
|
||||
// (Erc1155Wrapper.mintFungibleTokensAsync() in erc1155/test/utils/).
|
||||
// This is concise enough to justify duplication, but it sure is ugly.
|
||||
// tslint:disable-next-line no-unnecessary-type-assertion
|
||||
erc1155TokenId = ((await new LogDecoder(web3Wrapper, erc1155Artifacts).getTxWithDecodedLogsAsync(
|
||||
await erc1155MintableContract.create.sendTransactionAsync('uri:Dummy', /*isNonFungible:*/ false),
|
||||
)).logs[0] as LogWithDecodedArgs<ERC1155TransferSingleEventArgs>).args.id;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155MintableContract.mintFungible.sendTransactionAsync(
|
||||
erc1155TokenId,
|
||||
[tokenOwnerAddress],
|
||||
[new BigNumber(1)],
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
});
|
||||
|
||||
async function setERC20AllowanceAsync(): Promise<any> {
|
||||
return web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await new IERC20TokenContract(
|
||||
erc20Artifacts.IERC20Token.compilerOutput.abi,
|
||||
erc20TokenAddress,
|
||||
provider,
|
||||
).approve.sendTransactionAsync(approvedSpenderAddress, new BigNumber(1), { from: tokenOwnerAddress }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
|
||||
async function setERC721AllowanceAsync(): Promise<any> {
|
||||
return web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await new IERC721TokenContract(
|
||||
erc721Artifacts.IERC721Token.compilerOutput.abi,
|
||||
erc721TokenAddress,
|
||||
provider,
|
||||
).approve.sendTransactionAsync(approvedSpenderAddress, new BigNumber(1), { from: tokenOwnerAddress }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
|
||||
it('should have a deployed-to address', () => {
|
||||
expect(libAssetData.address.slice(0, 2)).to.equal('0x');
|
||||
});
|
||||
|
||||
it('should encode ERC20 asset data', async () => {
|
||||
expect(await libAssetData.encodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.address)).to.equal(
|
||||
KNOWN_ERC20_ENCODING.assetData,
|
||||
);
|
||||
});
|
||||
|
||||
it('should decode ERC20 asset data', async () => {
|
||||
expect(await libAssetData.decodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.assetData)).to.deep.equal([
|
||||
AssetProxyId.ERC20,
|
||||
KNOWN_ERC20_ENCODING.address,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should encode ERC721 asset data', async () => {
|
||||
expect(
|
||||
await libAssetData.encodeERC721AssetData.callAsync(
|
||||
KNOWN_ERC721_ENCODING.address,
|
||||
KNOWN_ERC721_ENCODING.tokenId,
|
||||
),
|
||||
).to.equal(KNOWN_ERC721_ENCODING.assetData);
|
||||
});
|
||||
|
||||
it('should decode ERC721 asset data', async () => {
|
||||
expect(await libAssetData.decodeERC721AssetData.callAsync(KNOWN_ERC721_ENCODING.assetData)).to.deep.equal([
|
||||
AssetProxyId.ERC721,
|
||||
KNOWN_ERC721_ENCODING.address,
|
||||
KNOWN_ERC721_ENCODING.tokenId,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should encode ERC1155 asset data', async () => {
|
||||
expect(
|
||||
await libAssetData.encodeERC1155AssetData.callAsync(
|
||||
KNOWN_ERC1155_ENCODING.tokenAddress,
|
||||
KNOWN_ERC1155_ENCODING.tokenIds,
|
||||
KNOWN_ERC1155_ENCODING.tokenValues,
|
||||
KNOWN_ERC1155_ENCODING.callbackData,
|
||||
),
|
||||
).to.equal(KNOWN_ERC1155_ENCODING.assetData);
|
||||
});
|
||||
|
||||
it('should decode ERC1155 asset data', async () => {
|
||||
expect(await libAssetData.decodeERC1155AssetData.callAsync(KNOWN_ERC1155_ENCODING.assetData)).to.deep.equal([
|
||||
AssetProxyId.ERC1155,
|
||||
KNOWN_ERC1155_ENCODING.tokenAddress,
|
||||
KNOWN_ERC1155_ENCODING.tokenIds,
|
||||
KNOWN_ERC1155_ENCODING.tokenValues,
|
||||
KNOWN_ERC1155_ENCODING.callbackData,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should encode multiasset data', async () => {
|
||||
expect(
|
||||
await libAssetData.encodeMultiAssetData.callAsync(
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts,
|
||||
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
|
||||
),
|
||||
).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData);
|
||||
});
|
||||
|
||||
it('should decode multiasset data', async () => {
|
||||
expect(await libAssetData.decodeMultiAssetData.callAsync(KNOWN_MULTI_ASSET_ENCODING.assetData)).to.deep.equal([
|
||||
AssetProxyId.MultiAsset,
|
||||
KNOWN_MULTI_ASSET_ENCODING.amounts,
|
||||
KNOWN_MULTI_ASSET_ENCODING.nestedAssetData,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should query ERC20 balance by asset data', async () => {
|
||||
expect(
|
||||
await libAssetData.getBalance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
),
|
||||
).to.bignumber.equal(erc20TokenTotalSupply);
|
||||
});
|
||||
|
||||
it('should query ERC721 balance by asset data', async () => {
|
||||
expect(
|
||||
await libAssetData.getBalance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
});
|
||||
|
||||
it('should query ERC1155 balances by asset data', async () => {
|
||||
expect(
|
||||
await libAssetData.getBalance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
await libAssetData.encodeERC1155AssetData.callAsync(
|
||||
erc1155MintableAddress,
|
||||
[erc1155TokenId],
|
||||
[new BigNumber(1)], // token values
|
||||
'0x', // callback data
|
||||
),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
});
|
||||
|
||||
it('should query multi-asset batch balance by asset data', async () => {
|
||||
expect(
|
||||
await libAssetData.getBalance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
await libAssetData.encodeMultiAssetData.callAsync(
|
||||
[new BigNumber(1), new BigNumber(1)],
|
||||
[
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
],
|
||||
),
|
||||
),
|
||||
).to.bignumber.equal(Math.min(erc20TokenTotalSupply.toNumber(), numberOfERC721Tokens));
|
||||
});
|
||||
|
||||
it('should query ERC20 allowances by asset data', async () => {
|
||||
await setERC20AllowanceAsync();
|
||||
expect(
|
||||
await libAssetData.getAllowance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
approvedSpenderAddress,
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
});
|
||||
|
||||
it('should query ERC721 approval by asset data', async () => {
|
||||
await setERC721AllowanceAsync();
|
||||
expect(
|
||||
await libAssetData.getAllowance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
approvedSpenderAddress,
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
});
|
||||
|
||||
it('should query ERC721 approvalForAll by assetData', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await new IERC721TokenContract(
|
||||
erc721Artifacts.IERC721Token.compilerOutput.abi,
|
||||
erc721TokenAddress,
|
||||
provider,
|
||||
).setApprovalForAll.sendTransactionAsync(anotherApprovedSpenderAddress, true, {
|
||||
from: tokenOwnerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
expect(
|
||||
await libAssetData.getAllowance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
anotherApprovedSpenderAddress,
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
});
|
||||
|
||||
it('should query ERC1155 allowances by asset data', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await new IERC1155MintableContract(
|
||||
erc1155Artifacts.IERC1155Mintable.compilerOutput.abi,
|
||||
erc1155MintableAddress,
|
||||
provider,
|
||||
).setApprovalForAll.sendTransactionAsync(approvedSpenderAddress, true, { from: tokenOwnerAddress }),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
expect(
|
||||
await libAssetData.getAllowance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
approvedSpenderAddress,
|
||||
await libAssetData.encodeERC1155AssetData.callAsync(
|
||||
erc1155MintableAddress,
|
||||
[erc1155TokenId],
|
||||
[new BigNumber(1)],
|
||||
'0x',
|
||||
),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
});
|
||||
|
||||
it('should query multi-asset allowances by asset data', async () => {
|
||||
await setERC20AllowanceAsync();
|
||||
await setERC721AllowanceAsync();
|
||||
expect(
|
||||
await libAssetData.getAllowance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
approvedSpenderAddress,
|
||||
await libAssetData.encodeMultiAssetData.callAsync(
|
||||
[new BigNumber(1), new BigNumber(1)],
|
||||
[
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
],
|
||||
),
|
||||
),
|
||||
).to.bignumber.equal(1);
|
||||
return;
|
||||
});
|
||||
|
||||
it('should query balances for a batch of asset data strings', async () => {
|
||||
expect(
|
||||
await libAssetData.getBatchBalances.callAsync(tokenOwnerAddress, [
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
]),
|
||||
).to.deep.equal([new BigNumber(erc20TokenTotalSupply), new BigNumber(1)]);
|
||||
});
|
||||
|
||||
it('should query allowances for a batch of asset data strings', async () => {
|
||||
await setERC20AllowanceAsync();
|
||||
await setERC721AllowanceAsync();
|
||||
expect(
|
||||
await libAssetData.getBatchAllowances.callAsync(tokenOwnerAddress, approvedSpenderAddress, [
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
await libAssetData.encodeERC721AssetData.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
]),
|
||||
).to.deep.equal([new BigNumber(1), new BigNumber(1)]);
|
||||
});
|
||||
|
||||
describe('getERC721TokenOwner', async () => {
|
||||
it('should return the null address when tokenId is not owned', async () => {
|
||||
const nonexistentTokenId = new BigNumber(1234567890);
|
||||
expect(
|
||||
await libAssetData.getERC721TokenOwner.callAsync(erc721TokenAddress, nonexistentTokenId),
|
||||
).to.be.equal(constants.NULL_ADDRESS);
|
||||
});
|
||||
it('should return the owner address when tokenId is owned', async () => {
|
||||
expect(
|
||||
await libAssetData.getERC721TokenOwner.callAsync(erc721TokenAddress, firstERC721TokenId),
|
||||
).to.be.equal(tokenOwnerAddress);
|
||||
});
|
||||
});
|
||||
|
||||
it('should query balance and allowance together, from asset data', async () => {
|
||||
await setERC20AllowanceAsync();
|
||||
expect(
|
||||
await libAssetData.getBalanceAndAllowance.callAsync(
|
||||
tokenOwnerAddress,
|
||||
approvedSpenderAddress,
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
),
|
||||
).to.deep.equal([new BigNumber(erc20TokenTotalSupply), new BigNumber(1)]);
|
||||
});
|
||||
|
||||
it('should query balances and allowances together, from an asset data array', async () => {
|
||||
await setERC20AllowanceAsync();
|
||||
expect(
|
||||
await libAssetData.getBatchBalancesAndAllowances.callAsync(tokenOwnerAddress, approvedSpenderAddress, [
|
||||
await libAssetData.encodeERC20AssetData.callAsync(erc20TokenAddress),
|
||||
]),
|
||||
).to.deep.equal([[new BigNumber(erc20TokenTotalSupply)], [new BigNumber(1)]]);
|
||||
});
|
||||
});
|
@@ -111,72 +111,62 @@ describe('Asset Transfer Proxies', () => {
|
||||
);
|
||||
|
||||
// Configure ERC20Proxy
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
authorized,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc20Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
multiAssetProxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure ERC721Proxy
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
authorized,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc721Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
multiAssetProxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure ERC115Proxy
|
||||
erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner);
|
||||
erc1155Proxy = await erc1155ProxyWrapper.deployProxyAsync();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
authorized,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc1155Proxy.addAuthorizedAddress.sendTransactionAsync(multiAssetProxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await erc1155Proxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
multiAssetProxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
// Configure MultiAssetProxy
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.addAuthorizedAddress.sendTransactionAsync(authorized, {
|
||||
from: owner,
|
||||
}),
|
||||
await multiAssetProxy.addAuthorizedAddress.awaitTransactionSuccessAsync(
|
||||
authorized,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
|
||||
erc20Proxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc721Proxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
|
||||
erc721Proxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multiAssetProxy.registerAssetProxy.sendTransactionAsync(erc1155Proxy.address, {
|
||||
from: owner,
|
||||
}),
|
||||
await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(
|
||||
erc1155Proxy.address,
|
||||
{ from: owner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
@@ -206,31 +196,26 @@ describe('Asset Transfer Proxies', () => {
|
||||
);
|
||||
|
||||
await erc20Wrapper.setBalancesAndAllowancesAsync();
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await noReturnErc20Token.setBalance.sendTransactionAsync(fromAddress, constants.INITIAL_ERC20_BALANCE),
|
||||
await noReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
|
||||
fromAddress,
|
||||
constants.INITIAL_ERC20_BALANCE,
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await noReturnErc20Token.approve.sendTransactionAsync(
|
||||
erc20Proxy.address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: fromAddress },
|
||||
),
|
||||
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
|
||||
erc20Proxy.address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: fromAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multipleReturnErc20Token.setBalance.sendTransactionAsync(
|
||||
fromAddress,
|
||||
constants.INITIAL_ERC20_BALANCE,
|
||||
),
|
||||
await multipleReturnErc20Token.setBalance.awaitTransactionSuccessAsync(
|
||||
fromAddress,
|
||||
constants.INITIAL_ERC20_BALANCE,
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await multipleReturnErc20Token.approve.sendTransactionAsync(
|
||||
erc20Proxy.address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: fromAddress },
|
||||
),
|
||||
await multipleReturnErc20Token.approve.awaitTransactionSuccessAsync(
|
||||
erc20Proxy.address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: fromAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
|
||||
@@ -419,10 +404,10 @@ describe('Asset Transfer Proxies', () => {
|
||||
toAddress,
|
||||
amount,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, allowance, {
|
||||
from: fromAddress,
|
||||
}),
|
||||
await erc20TokenA.approve.awaitTransactionSuccessAsync(
|
||||
erc20Proxy.address,
|
||||
allowance,
|
||||
{ from: fromAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const erc20Balances = await erc20Wrapper.getBalancesAsync();
|
||||
@@ -451,10 +436,10 @@ describe('Asset Transfer Proxies', () => {
|
||||
toAddress,
|
||||
amount,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await noReturnErc20Token.approve.sendTransactionAsync(erc20Proxy.address, allowance, {
|
||||
from: fromAddress,
|
||||
}),
|
||||
await noReturnErc20Token.approve.awaitTransactionSuccessAsync(
|
||||
erc20Proxy.address,
|
||||
allowance,
|
||||
{ from: fromAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const initialFromBalance = await noReturnErc20Token.balanceOf.callAsync(fromAddress);
|
||||
@@ -692,10 +677,10 @@ describe('Asset Transfer Proxies', () => {
|
||||
const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId);
|
||||
expect(ownerFromAsset).to.be.equal(fromAddress);
|
||||
// Remove transfer approval for fromAddress.
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721TokenA.approve.sendTransactionAsync(constants.NULL_ADDRESS, erc721AFromTokenId, {
|
||||
from: fromAddress,
|
||||
}),
|
||||
await erc721TokenA.approve.awaitTransactionSuccessAsync(
|
||||
constants.NULL_ADDRESS,
|
||||
erc721AFromTokenId,
|
||||
{ from: fromAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
// Perform a transfer; expect this to fail.
|
||||
|
@@ -115,7 +115,7 @@ export class ERC1155ProxyWrapper {
|
||||
valuesToTransfer,
|
||||
receiverCallbackData,
|
||||
);
|
||||
if (!_.isUndefined(extraData)) {
|
||||
if (extraData !== undefined) {
|
||||
encodedAssetData = `${encodedAssetData}${extraData}`;
|
||||
}
|
||||
const data = this._assetProxyInterface.transferFrom.getABIEncodedTransactionData(
|
||||
@@ -199,10 +199,10 @@ export class ERC1155ProxyWrapper {
|
||||
// Mint tokens for each owner for this token
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
if (_.isUndefined(fungibleHoldingsByOwner[tokenOwnerAddress])) {
|
||||
if (fungibleHoldingsByOwner[tokenOwnerAddress] === undefined) {
|
||||
fungibleHoldingsByOwner[tokenOwnerAddress] = {};
|
||||
}
|
||||
if (_.isUndefined(fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress])) {
|
||||
if (fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] === undefined) {
|
||||
fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] = {};
|
||||
}
|
||||
fungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString] =
|
||||
@@ -221,13 +221,13 @@ export class ERC1155ProxyWrapper {
|
||||
const tokenIdAsString = tokenId.toString();
|
||||
this._nonFungibleTokenIds.push(tokenIdAsString);
|
||||
_.each(this._tokenOwnerAddresses, async (tokenOwnerAddress: string, i: number) => {
|
||||
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress])) {
|
||||
if (nonFungibleHoldingsByOwner[tokenOwnerAddress] === undefined) {
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress] = {};
|
||||
}
|
||||
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress])) {
|
||||
if (nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] === undefined) {
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress] = {};
|
||||
}
|
||||
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString])) {
|
||||
if (nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString] === undefined) {
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress][dummyAddress][tokenIdAsString] = [];
|
||||
}
|
||||
this._nfts.push({ id: nftIds[i], tokenId });
|
||||
@@ -278,26 +278,25 @@ export class ERC1155ProxyWrapper {
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
// Fungible tokens
|
||||
for (const tokenId of this._fungibleTokenIds) {
|
||||
if (_.isUndefined(tokenHoldingsByOwner[tokenOwnerAddress])) {
|
||||
if (tokenHoldingsByOwner[tokenOwnerAddress] === undefined) {
|
||||
tokenHoldingsByOwner[tokenOwnerAddress] = {};
|
||||
}
|
||||
if (_.isUndefined(tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress])) {
|
||||
if (tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress] === undefined) {
|
||||
tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress] = {};
|
||||
}
|
||||
tokenHoldingsByOwner[tokenOwnerAddress][tokenAddress][tokenId] = balances[i++];
|
||||
}
|
||||
// Non-fungible tokens
|
||||
for (const nft of this._nfts) {
|
||||
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress])) {
|
||||
if (nonFungibleHoldingsByOwner[tokenOwnerAddress] === undefined) {
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress] = {};
|
||||
}
|
||||
if (_.isUndefined(nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress])) {
|
||||
if (nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress] === undefined) {
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress] = {};
|
||||
}
|
||||
if (
|
||||
_.isUndefined(
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress][nft.tokenId.toString()],
|
||||
)
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress][nft.tokenId.toString()] ===
|
||||
undefined
|
||||
) {
|
||||
nonFungibleHoldingsByOwner[tokenOwnerAddress][tokenAddress][nft.tokenId.toString()] = [];
|
||||
}
|
||||
@@ -348,25 +347,25 @@ export class ERC1155ProxyWrapper {
|
||||
const tokenWrapper = _.find(this._dummyTokenWrappers, (wrapper: Erc1155Wrapper) => {
|
||||
return wrapper.getContract().address === contractAddress;
|
||||
});
|
||||
if (_.isUndefined(tokenWrapper)) {
|
||||
if (tokenWrapper === undefined) {
|
||||
throw new Error(`Contract: ${contractAddress} was not deployed through ERC1155ProxyWrapper`);
|
||||
}
|
||||
return tokenWrapper;
|
||||
}
|
||||
private _getContractFromAddress(tokenAddress: string): ERC1155MintableContract {
|
||||
const tokenContractIfExists = _.find(this._dummyTokenWrappers, c => c.getContract().address === tokenAddress);
|
||||
if (_.isUndefined(tokenContractIfExists)) {
|
||||
if (tokenContractIfExists === undefined) {
|
||||
throw new Error(`Token: ${tokenAddress} was not deployed through ERC1155ProxyWrapper`);
|
||||
}
|
||||
return tokenContractIfExists.getContract();
|
||||
}
|
||||
private _validateDummyTokenContractsExistOrThrow(): void {
|
||||
if (_.isUndefined(this._dummyTokenWrappers)) {
|
||||
if (this._dummyTokenWrappers === undefined) {
|
||||
throw new Error('Dummy ERC1155 tokens not yet deployed, please call "deployDummyTokensAsync"');
|
||||
}
|
||||
}
|
||||
private _validateProxyContractExistsOrThrow(): void {
|
||||
if (_.isUndefined(this._proxyContract)) {
|
||||
if (this._proxyContract === undefined) {
|
||||
throw new Error('ERC1155 proxy contract not yet deployed, please call "deployProxyAsync"');
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@ import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contra
|
||||
import { constants, ERC20BalancesByOwner, txDefaults } from '@0x/contracts-test-utils';
|
||||
import { assetDataUtils } from '@0x/order-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { ZeroExProvider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@@ -11,7 +10,6 @@ import { artifacts, ERC20ProxyContract } from '../../src';
|
||||
export class ERC20Wrapper {
|
||||
private readonly _tokenOwnerAddresses: string[];
|
||||
private readonly _contractOwnerAddress: string;
|
||||
private readonly _web3Wrapper: Web3Wrapper;
|
||||
private readonly _provider: ZeroExProvider;
|
||||
private readonly _dummyTokenContracts: DummyERC20TokenContract[];
|
||||
private _proxyContract?: ERC20ProxyContract;
|
||||
@@ -25,7 +23,6 @@ export class ERC20Wrapper {
|
||||
*/
|
||||
constructor(provider: ZeroExProvider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
|
||||
this._dummyTokenContracts = [];
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._provider = provider;
|
||||
this._tokenOwnerAddresses = tokenOwnerAddresses;
|
||||
this._contractOwnerAddress = contractOwnerAddress;
|
||||
@@ -67,20 +64,16 @@ export class ERC20Wrapper {
|
||||
this._validateProxyContractExistsOrThrow();
|
||||
for (const dummyTokenContract of this._dummyTokenContracts) {
|
||||
for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dummyTokenContract.setBalance.sendTransactionAsync(
|
||||
tokenOwnerAddress,
|
||||
constants.INITIAL_ERC20_BALANCE,
|
||||
{ from: this._contractOwnerAddress },
|
||||
),
|
||||
await dummyTokenContract.setBalance.awaitTransactionSuccessAsync(
|
||||
tokenOwnerAddress,
|
||||
constants.INITIAL_ERC20_BALANCE,
|
||||
{ from: this._contractOwnerAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await dummyTokenContract.approve.sendTransactionAsync(
|
||||
(this._proxyContract as ERC20ProxyContract).address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: tokenOwnerAddress },
|
||||
),
|
||||
await dummyTokenContract.approve.awaitTransactionSuccessAsync(
|
||||
(this._proxyContract as ERC20ProxyContract).address,
|
||||
constants.INITIAL_ERC20_ALLOWANCE,
|
||||
{ from: tokenOwnerAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
@@ -93,10 +86,10 @@ export class ERC20Wrapper {
|
||||
}
|
||||
public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
|
||||
const tokenContract = this._getTokenContractFromAssetData(assetData);
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.setBalance.sendTransactionAsync(userAddress, amount, {
|
||||
from: this._contractOwnerAddress,
|
||||
}),
|
||||
await tokenContract.setBalance.awaitTransactionSuccessAsync(
|
||||
userAddress,
|
||||
amount,
|
||||
{ from: this._contractOwnerAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
@@ -109,10 +102,10 @@ export class ERC20Wrapper {
|
||||
public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
|
||||
const tokenContract = this._getTokenContractFromAssetData(assetData);
|
||||
const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.approve.sendTransactionAsync(proxyAddress, amount, {
|
||||
from: userAddress,
|
||||
}),
|
||||
await tokenContract.approve.awaitTransactionSuccessAsync(
|
||||
proxyAddress,
|
||||
amount,
|
||||
{ from: userAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
@@ -133,7 +126,7 @@ export class ERC20Wrapper {
|
||||
_.forEach(balances, (balance, balanceIndex) => {
|
||||
const tokenAddress = balanceInfo[balanceIndex].tokenAddress;
|
||||
const tokenOwnerAddress = balanceInfo[balanceIndex].tokenOwnerAddress;
|
||||
if (_.isUndefined(balancesByOwner[tokenOwnerAddress])) {
|
||||
if (balancesByOwner[tokenOwnerAddress] === undefined) {
|
||||
balancesByOwner[tokenOwnerAddress] = {};
|
||||
}
|
||||
const wrappedBalance = new BigNumber(balance);
|
||||
@@ -142,7 +135,7 @@ export class ERC20Wrapper {
|
||||
return balancesByOwner;
|
||||
}
|
||||
public addDummyTokenContract(dummy: DummyERC20TokenContract): void {
|
||||
if (!_.isUndefined(this._dummyTokenContracts)) {
|
||||
if (this._dummyTokenContracts !== undefined) {
|
||||
this._dummyTokenContracts.push(dummy);
|
||||
}
|
||||
}
|
||||
@@ -160,18 +153,18 @@ export class ERC20Wrapper {
|
||||
const erc20ProxyData = assetDataUtils.decodeERC20AssetData(assetData);
|
||||
const tokenAddress = erc20ProxyData.tokenAddress;
|
||||
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
|
||||
if (_.isUndefined(tokenContractIfExists)) {
|
||||
if (tokenContractIfExists === undefined) {
|
||||
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
|
||||
}
|
||||
return tokenContractIfExists;
|
||||
}
|
||||
private _validateDummyTokenContractsExistOrThrow(): void {
|
||||
if (_.isUndefined(this._dummyTokenContracts)) {
|
||||
if (this._dummyTokenContracts === undefined) {
|
||||
throw new Error('Dummy ERC20 tokens not yet deployed, please call "deployDummyTokensAsync"');
|
||||
}
|
||||
}
|
||||
private _validateProxyContractExistsOrThrow(): void {
|
||||
if (_.isUndefined(this._proxyContract)) {
|
||||
if (this._proxyContract === undefined) {
|
||||
throw new Error('ERC20 proxy contract not yet deployed, please call "deployProxyAsync"');
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@ import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/cont
|
||||
import { constants, ERC721TokenIdsByOwner, txDefaults } from '@0x/contracts-test-utils';
|
||||
import { generatePseudoRandomSalt } from '@0x/order-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { ZeroExProvider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
@@ -11,14 +10,12 @@ import { artifacts, ERC721ProxyContract } from '../../src';
|
||||
export class ERC721Wrapper {
|
||||
private readonly _tokenOwnerAddresses: string[];
|
||||
private readonly _contractOwnerAddress: string;
|
||||
private readonly _web3Wrapper: Web3Wrapper;
|
||||
private readonly _provider: ZeroExProvider;
|
||||
private readonly _dummyTokenContracts: DummyERC721TokenContract[];
|
||||
private _proxyContract?: ERC721ProxyContract;
|
||||
private _proxyIdIfExists?: string;
|
||||
private _initialTokenIdsByOwner: ERC721TokenIdsByOwner = {};
|
||||
constructor(provider: ZeroExProvider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
|
||||
this._web3Wrapper = new Web3Wrapper(provider);
|
||||
this._provider = provider;
|
||||
this._dummyTokenContracts = [];
|
||||
this._tokenOwnerAddresses = tokenOwnerAddresses;
|
||||
@@ -62,12 +59,12 @@ export class ERC721Wrapper {
|
||||
for (const i of _.times(constants.NUM_ERC721_TOKENS_TO_MINT)) {
|
||||
const tokenId = generatePseudoRandomSalt();
|
||||
await this.mintAsync(dummyTokenContract.address, tokenId, tokenOwnerAddress);
|
||||
if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress])) {
|
||||
if (this._initialTokenIdsByOwner[tokenOwnerAddress] === undefined) {
|
||||
this._initialTokenIdsByOwner[tokenOwnerAddress] = {
|
||||
[dummyTokenContract.address]: [],
|
||||
};
|
||||
}
|
||||
if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address])) {
|
||||
if (this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] === undefined) {
|
||||
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] = [];
|
||||
}
|
||||
this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address].push(tokenId);
|
||||
@@ -91,20 +88,20 @@ export class ERC721Wrapper {
|
||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
|
||||
const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.setApprovalForAll.sendTransactionAsync(proxyAddress, isApproved, {
|
||||
from: tokenOwner,
|
||||
}),
|
||||
await tokenContract.setApprovalForAll.awaitTransactionSuccessAsync(
|
||||
proxyAddress,
|
||||
isApproved,
|
||||
{ from: tokenOwner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
|
||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||
const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.approve.sendTransactionAsync(to, tokenId, {
|
||||
from: tokenOwner,
|
||||
}),
|
||||
await tokenContract.approve.awaitTransactionSuccessAsync(
|
||||
to,
|
||||
tokenId,
|
||||
{ from: tokenOwner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
@@ -115,28 +112,29 @@ export class ERC721Wrapper {
|
||||
userAddress: string,
|
||||
): Promise<void> {
|
||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.transferFrom.sendTransactionAsync(currentOwner, userAddress, tokenId, {
|
||||
from: currentOwner,
|
||||
}),
|
||||
await tokenContract.transferFrom.awaitTransactionSuccessAsync(
|
||||
currentOwner,
|
||||
userAddress,
|
||||
tokenId,
|
||||
{ from: currentOwner },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
|
||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.mint.sendTransactionAsync(userAddress, tokenId, {
|
||||
from: this._contractOwnerAddress,
|
||||
}),
|
||||
await tokenContract.mint.awaitTransactionSuccessAsync(
|
||||
userAddress,
|
||||
tokenId,
|
||||
{ from: this._contractOwnerAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
|
||||
const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
|
||||
await this._web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await tokenContract.burn.sendTransactionAsync(owner, tokenId, {
|
||||
from: this._contractOwnerAddress,
|
||||
}),
|
||||
await tokenContract.burn.awaitTransactionSuccessAsync(
|
||||
owner,
|
||||
tokenId,
|
||||
{ from: this._contractOwnerAddress },
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
}
|
||||
@@ -189,12 +187,12 @@ export class ERC721Wrapper {
|
||||
_.forEach(tokenOwnerAddresses, (tokenOwnerAddress, ownerIndex) => {
|
||||
const tokenAddress = tokenInfo[ownerIndex].tokenAddress;
|
||||
const tokenId = tokenInfo[ownerIndex].tokenId;
|
||||
if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress])) {
|
||||
if (tokenIdsByOwner[tokenOwnerAddress] === undefined) {
|
||||
tokenIdsByOwner[tokenOwnerAddress] = {
|
||||
[tokenAddress]: [],
|
||||
};
|
||||
}
|
||||
if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress][tokenAddress])) {
|
||||
if (tokenIdsByOwner[tokenOwnerAddress][tokenAddress] === undefined) {
|
||||
tokenIdsByOwner[tokenOwnerAddress][tokenAddress] = [];
|
||||
}
|
||||
tokenIdsByOwner[tokenOwnerAddress][tokenAddress].push(tokenId);
|
||||
@@ -210,18 +208,18 @@ export class ERC721Wrapper {
|
||||
}
|
||||
private _getTokenContractFromAssetData(tokenAddress: string): DummyERC721TokenContract {
|
||||
const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
|
||||
if (_.isUndefined(tokenContractIfExists)) {
|
||||
if (tokenContractIfExists === undefined) {
|
||||
throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
|
||||
}
|
||||
return tokenContractIfExists;
|
||||
}
|
||||
private _validateDummyTokenContractsExistOrThrow(): void {
|
||||
if (_.isUndefined(this._dummyTokenContracts)) {
|
||||
if (this._dummyTokenContracts === undefined) {
|
||||
throw new Error('Dummy ERC721 tokens not yet deployed, please call "deployDummyTokensAsync"');
|
||||
}
|
||||
}
|
||||
private _validateProxyContractExistsOrThrow(): void {
|
||||
if (_.isUndefined(this._proxyContract)) {
|
||||
if (this._proxyContract === undefined) {
|
||||
throw new Error('ERC721 proxy contract not yet deployed, please call "deployProxyAsync"');
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
"generated-artifacts/IAssetData.json",
|
||||
"generated-artifacts/IAssetProxy.json",
|
||||
"generated-artifacts/IAuthorizable.json",
|
||||
"generated-artifacts/LibAssetData.json",
|
||||
"generated-artifacts/MixinAuthorizable.json",
|
||||
"generated-artifacts/MultiAssetProxy.json"
|
||||
],
|
||||
|
@@ -1,4 +1,37 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "2.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Make `decodeOrdersFromFillData`, `getCoordinatorApprovalHash`, and `getTransactionHash` public",
|
||||
"pr": 1729
|
||||
},
|
||||
{
|
||||
"note": "Make `assertValidTransactionOrdersApproval` internal",
|
||||
"pr": 1729
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.0.1 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.0 - _April 11, 2019_
|
||||
|
||||
* Make `decodeOrdersFromFillData`, `getCoordinatorApprovalHash`, and `getTransactionHash` public (#1729)
|
||||
* Make `assertValidTransactionOrdersApproval` internal (#1729)
|
||||
|
||||
## v1.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v1.0.0 - _March 20, 2019_
|
||||
|
||||
* Created Coordinator package
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": {
|
||||
@@ -21,10 +21,5 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"contracts": [
|
||||
"src/Coordinator.sol",
|
||||
"src/registry/CoordinatorRegistry.sol",
|
||||
"test/TestLibs.sol",
|
||||
"test/TestMixins.sol"
|
||||
]
|
||||
"contracts": ["src/Coordinator.sol", "src/registry/CoordinatorRegistry.sol"]
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
view
|
||||
{
|
||||
// Get the orders from the the Exchange calldata in the 0x transaction
|
||||
LibOrder.Order[] memory orders = decodeFillDataOrders(transaction.data);
|
||||
LibOrder.Order[] memory orders = decodeOrdersFromFillData(transaction.data);
|
||||
|
||||
// No approval is required for non-fill methods
|
||||
if (orders.length > 0) {
|
||||
@@ -74,6 +74,57 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Decodes the orders from Exchange calldata representing any fill method.
|
||||
/// @param data Exchange calldata representing a fill method.
|
||||
/// @return The orders from the Exchange calldata.
|
||||
function decodeOrdersFromFillData(bytes memory data)
|
||||
public
|
||||
pure
|
||||
returns (LibOrder.Order[] memory orders)
|
||||
{
|
||||
bytes4 selector = data.readBytes4(0);
|
||||
if (
|
||||
selector == FILL_ORDER_SELECTOR ||
|
||||
selector == FILL_ORDER_NO_THROW_SELECTOR ||
|
||||
selector == FILL_OR_KILL_ORDER_SELECTOR
|
||||
) {
|
||||
// Decode single order
|
||||
(LibOrder.Order memory order) = abi.decode(
|
||||
data.slice(4, data.length),
|
||||
(LibOrder.Order)
|
||||
);
|
||||
orders = new LibOrder.Order[](1);
|
||||
orders[0] = order;
|
||||
} else if (
|
||||
selector == BATCH_FILL_ORDERS_SELECTOR ||
|
||||
selector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR ||
|
||||
selector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR ||
|
||||
selector == MARKET_BUY_ORDERS_SELECTOR ||
|
||||
selector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR ||
|
||||
selector == MARKET_SELL_ORDERS_SELECTOR ||
|
||||
selector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
|
||||
) {
|
||||
// Decode all orders
|
||||
// solhint-disable indent
|
||||
(orders) = abi.decode(
|
||||
data.slice(4, data.length),
|
||||
(LibOrder.Order[])
|
||||
);
|
||||
} else if (selector == MATCH_ORDERS_SELECTOR) {
|
||||
// Decode left and right orders
|
||||
(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(
|
||||
data.slice(4, data.length),
|
||||
(LibOrder.Order, LibOrder.Order)
|
||||
);
|
||||
|
||||
// Create array of orders
|
||||
orders = new LibOrder.Order[](2);
|
||||
orders[0] = leftOrder;
|
||||
orders[1] = rightOrder;
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
|
||||
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param orders Array of order structs containing order specifications.
|
||||
@@ -89,7 +140,7 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
public
|
||||
internal
|
||||
view
|
||||
{
|
||||
// Verify that Ethereum tx signer is the same as the approved txOrigin
|
||||
@@ -149,55 +200,4 @@ contract MixinCoordinatorApprovalVerifier is
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Decodes the orders from Exchange calldata representing any fill method.
|
||||
/// @param data Exchange calldata representing a fill method.
|
||||
/// @return The orders from the Exchange calldata.
|
||||
function decodeFillDataOrders(bytes memory data)
|
||||
internal
|
||||
pure
|
||||
returns (LibOrder.Order[] memory orders)
|
||||
{
|
||||
bytes4 selector = data.readBytes4(0);
|
||||
if (
|
||||
selector == FILL_ORDER_SELECTOR ||
|
||||
selector == FILL_ORDER_NO_THROW_SELECTOR ||
|
||||
selector == FILL_OR_KILL_ORDER_SELECTOR
|
||||
) {
|
||||
// Decode single order
|
||||
(LibOrder.Order memory order) = abi.decode(
|
||||
data.slice(4, data.length),
|
||||
(LibOrder.Order)
|
||||
);
|
||||
orders = new LibOrder.Order[](1);
|
||||
orders[0] = order;
|
||||
} else if (
|
||||
selector == BATCH_FILL_ORDERS_SELECTOR ||
|
||||
selector == BATCH_FILL_ORDERS_NO_THROW_SELECTOR ||
|
||||
selector == BATCH_FILL_OR_KILL_ORDERS_SELECTOR ||
|
||||
selector == MARKET_BUY_ORDERS_SELECTOR ||
|
||||
selector == MARKET_BUY_ORDERS_NO_THROW_SELECTOR ||
|
||||
selector == MARKET_SELL_ORDERS_SELECTOR ||
|
||||
selector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
|
||||
) {
|
||||
// Decode all orders
|
||||
// solhint-disable indent
|
||||
(orders) = abi.decode(
|
||||
data.slice(4, data.length),
|
||||
(LibOrder.Order[])
|
||||
);
|
||||
} else if (selector == MATCH_ORDERS_SELECTOR) {
|
||||
// Decode left and right orders
|
||||
(LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder) = abi.decode(
|
||||
data.slice(4, data.length),
|
||||
(LibOrder.Order, LibOrder.Order)
|
||||
);
|
||||
|
||||
// Create array of orders
|
||||
orders = new LibOrder.Order[](2);
|
||||
orders[0] = leftOrder;
|
||||
orders[1] = rightOrder;
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
}
|
||||
|
@@ -42,21 +42,11 @@ contract ICoordinatorApprovalVerifier {
|
||||
public
|
||||
view;
|
||||
|
||||
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param orders Array of order structs containing order specifications.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
|
||||
function assertValidTransactionOrdersApproval(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
LibOrder.Order[] memory orders,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
/// @dev Decodes the orders from Exchange calldata representing any fill method.
|
||||
/// @param data Exchange calldata representing a fill method.
|
||||
/// @return The orders from the Exchange calldata.
|
||||
function decodeOrdersFromFillData(bytes memory data)
|
||||
public
|
||||
view;
|
||||
pure
|
||||
returns (LibOrder.Order[] memory orders);
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental "ABIEncoderV2";
|
||||
|
||||
import "./LibEIP712Domain.sol";
|
||||
|
||||
@@ -37,16 +38,16 @@ contract LibCoordinatorApproval is
|
||||
|
||||
struct CoordinatorApproval {
|
||||
address txOrigin; // Required signer of Ethereum transaction that is submitting approval.
|
||||
bytes32 transactionHash; // EIP712 hash of the transaction, using the domain separator of this contract.
|
||||
bytes32 transactionHash; // EIP712 hash of the transaction.
|
||||
bytes transactionSignature; // Signature of the 0x transaction.
|
||||
uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the signature expires.
|
||||
uint256 approvalExpirationTimeSeconds; // Timestamp in seconds for which the approval expires.
|
||||
}
|
||||
|
||||
/// @dev Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract.
|
||||
/// @param approval Coordinator approval message containing the transaction hash, transaction signature, and expiration of the approval.
|
||||
/// @return EIP712 hash of the Coordinator approval message with the domain separator of this contract.
|
||||
function getCoordinatorApprovalHash(CoordinatorApproval memory approval)
|
||||
internal
|
||||
public
|
||||
view
|
||||
returns (bytes32 approvalHash)
|
||||
{
|
||||
@@ -71,9 +72,10 @@ contract LibCoordinatorApproval is
|
||||
// Assembly for more efficiently computing:
|
||||
// keccak256(abi.encodePacked(
|
||||
// EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH,
|
||||
// approval.txOrigin,
|
||||
// approval.transactionHash,
|
||||
// keccak256(approval.transactionSignature)
|
||||
// approval.expiration,
|
||||
// approval.approvalExpirationTimeSeconds,
|
||||
// ));
|
||||
|
||||
assembly {
|
||||
|
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental "ABIEncoderV2";
|
||||
|
||||
import "./LibEIP712Domain.sol";
|
||||
|
||||
@@ -40,11 +41,11 @@ contract LibZeroExTransaction is
|
||||
bytes data; // AbiV2 encoded calldata.
|
||||
}
|
||||
|
||||
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of this contract.
|
||||
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @return EIP712 hash of the transaction with the domain separator of this contract.
|
||||
function getTransactionHash(ZeroExTransaction memory transaction)
|
||||
internal
|
||||
public
|
||||
view
|
||||
returns (bytes32 transactionHash)
|
||||
{
|
||||
|
@@ -26,11 +26,21 @@ import "../interfaces/ICoordinatorApprovalVerifier.sol";
|
||||
contract MCoordinatorApprovalVerifier is
|
||||
ICoordinatorApprovalVerifier
|
||||
{
|
||||
/// @dev Decodes the orders from Exchange calldata representing any fill method.
|
||||
/// @param data Exchange calldata representing a fill method.
|
||||
/// @return The orders from the Exchange calldata.
|
||||
function decodeFillDataOrders(bytes memory data)
|
||||
/// @dev Validates that the feeRecipients of a batch of order have approved a 0x transaction.
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @param orders Array of order structs containing order specifications.
|
||||
/// @param txOrigin Required signer of Ethereum transaction calling this function.
|
||||
/// @param transactionSignature Proof that the transaction has been signed by the signer.
|
||||
/// @param approvalExpirationTimeSeconds Array of expiration times in seconds for which each corresponding approval signature expires.
|
||||
/// @param approvalSignatures Array of signatures that correspond to the feeRecipients of each order.
|
||||
function assertValidTransactionOrdersApproval(
|
||||
LibZeroExTransaction.ZeroExTransaction memory transaction,
|
||||
LibOrder.Order[] memory orders,
|
||||
address txOrigin,
|
||||
bytes memory transactionSignature,
|
||||
uint256[] memory approvalExpirationTimeSeconds,
|
||||
bytes[] memory approvalSignatures
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (LibOrder.Order[] memory orders);
|
||||
view;
|
||||
}
|
||||
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 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.5.5;
|
||||
pragma experimental "ABIEncoderV2";
|
||||
|
||||
import "../src/libs/LibConstants.sol";
|
||||
import "../src/libs/LibCoordinatorApproval.sol";
|
||||
import "../src/libs/LibZeroExTransaction.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract TestLibs is
|
||||
LibConstants,
|
||||
LibCoordinatorApproval,
|
||||
LibZeroExTransaction
|
||||
{
|
||||
constructor (address _exchange)
|
||||
public
|
||||
LibConstants(_exchange)
|
||||
{}
|
||||
|
||||
/// @dev Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract.
|
||||
/// @param approval Coordinator approval message containing the transaction hash, transaction signature, and expiration of the approval.
|
||||
/// @return EIP712 hash of the Coordinator approval message with the domain separator of this contract.
|
||||
function publicGetCoordinatorApprovalHash(CoordinatorApproval memory approval)
|
||||
public
|
||||
view
|
||||
returns (bytes32 approvalHash)
|
||||
{
|
||||
approvalHash = getCoordinatorApprovalHash(approval);
|
||||
return approvalHash;
|
||||
}
|
||||
|
||||
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.
|
||||
/// @param transaction 0x transaction containing salt, signerAddress, and data.
|
||||
/// @return EIP712 hash of the transaction with the domain separator of the Exchange contract.
|
||||
function publicGetTransactionHash(ZeroExTransaction memory transaction)
|
||||
public
|
||||
view
|
||||
returns (bytes32 transactionHash)
|
||||
{
|
||||
transactionHash = getTransactionHash(transaction);
|
||||
return transactionHash;
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 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.5.5;
|
||||
pragma experimental "ABIEncoderV2";
|
||||
|
||||
import "../src/libs/LibConstants.sol";
|
||||
import "../src/MixinSignatureValidator.sol";
|
||||
import "../src/MixinCoordinatorApprovalVerifier.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract TestMixins is
|
||||
LibConstants,
|
||||
MixinSignatureValidator,
|
||||
MixinCoordinatorApprovalVerifier
|
||||
{
|
||||
constructor (address _exchange)
|
||||
public
|
||||
LibConstants(_exchange)
|
||||
{}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-coordinator",
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -33,7 +34,7 @@
|
||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry|TestLibs|TestMixins).json",
|
||||
"abis": "./generated-artifacts/@(Coordinator|CoordinatorRegistry).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,18 +68,18 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-asset-proxy": "^2.0.0",
|
||||
"@0x/contracts-erc20": "^2.0.0",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-asset-proxy": "^2.1.2",
|
||||
"@0x/contracts-erc20": "^2.2.1",
|
||||
"@0x/contracts-exchange": "1.0.2",
|
||||
"@0x/contracts-exchange-libs": "^2.0.0",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/order-utils": "^7.1.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/contracts-exchange-libs": "^2.1.2",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/order-utils": "^8.0.0",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -7,11 +7,7 @@ import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as Coordinator from '../generated-artifacts/Coordinator.json';
|
||||
import * as CoordinatorRegistry from '../generated-artifacts/CoordinatorRegistry.json';
|
||||
import * as TestLibs from '../generated-artifacts/TestLibs.json';
|
||||
import * as TestMixins from '../generated-artifacts/TestMixins.json';
|
||||
export const artifacts = {
|
||||
Coordinator: Coordinator as ContractArtifact,
|
||||
CoordinatorRegistry: CoordinatorRegistry as ContractArtifact,
|
||||
TestLibs: TestLibs as ContractArtifact,
|
||||
TestMixins: TestMixins as ContractArtifact,
|
||||
};
|
||||
|
@@ -5,5 +5,3 @@
|
||||
*/
|
||||
export * from '../generated-wrappers/coordinator';
|
||||
export * from '../generated-wrappers/coordinator_registry';
|
||||
export * from '../generated-wrappers/test_libs';
|
||||
export * from '../generated-wrappers/test_mixins';
|
||||
|
@@ -435,7 +435,7 @@ describe('Coordinator tests', () => {
|
||||
describe('cancels', () => {
|
||||
it('cancelOrder call should be successful without an approval', async () => {
|
||||
const orders = [await orderFactory.newSignedOrderAsync()];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDER, orders);
|
||||
const transaction = makerTransactionFactory.newSignedTransaction(data);
|
||||
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await coordinatorContract.executeTransaction.sendTransactionAsync(
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -4,14 +4,14 @@ import { transactionHashUtils } from '@0x/order-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as chai from 'chai';
|
||||
|
||||
import { artifacts, hashUtils, TestLibsContract } from '../src';
|
||||
import { artifacts, CoordinatorContract, hashUtils } from '../src';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
describe('Libs tests', () => {
|
||||
let testLibs: TestLibsContract;
|
||||
let coordinatorContract: CoordinatorContract;
|
||||
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
|
||||
|
||||
before(async () => {
|
||||
@@ -21,8 +21,8 @@ describe('Libs tests', () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
before(async () => {
|
||||
testLibs = await TestLibsContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestLibs,
|
||||
coordinatorContract = await CoordinatorContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Coordinator,
|
||||
provider,
|
||||
txDefaults,
|
||||
exchangeAddress,
|
||||
@@ -44,7 +44,7 @@ describe('Libs tests', () => {
|
||||
data: '0x1234',
|
||||
};
|
||||
const expectedTxHash = transactionHashUtils.getTransactionHashHex(tx);
|
||||
const txHash = await testLibs.publicGetTransactionHash.callAsync(tx);
|
||||
const txHash = await coordinatorContract.getTransactionHash.callAsync(tx);
|
||||
expect(expectedTxHash).to.eq(txHash);
|
||||
});
|
||||
});
|
||||
@@ -68,11 +68,11 @@ describe('Libs tests', () => {
|
||||
};
|
||||
const expectedApprovalHash = hashUtils.getApprovalHashHex(
|
||||
signedTx,
|
||||
testLibs.address,
|
||||
coordinatorContract.address,
|
||||
txOrigin,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approvalHash = await testLibs.publicGetCoordinatorApprovalHash.callAsync(approval);
|
||||
const approvalHash = await coordinatorContract.getCoordinatorApprovalHash.callAsync(approval);
|
||||
expect(expectedApprovalHash).to.eq(approvalHash);
|
||||
});
|
||||
});
|
||||
|
@@ -16,7 +16,7 @@ import { BigNumber } from '@0x/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
|
||||
import { ApprovalFactory, artifacts, constants, exchangeDataEncoder, TestMixinsContract } from '../src';
|
||||
import { ApprovalFactory, artifacts, constants, CoordinatorContract, exchangeDataEncoder } from '../src';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
@@ -26,7 +26,7 @@ describe('Mixins tests', () => {
|
||||
let transactionSignerAddress: string;
|
||||
let approvalSignerAddress1: string;
|
||||
let approvalSignerAddress2: string;
|
||||
let mixins: TestMixinsContract;
|
||||
let mixins: CoordinatorContract;
|
||||
let transactionFactory: TransactionFactory;
|
||||
let approvalFactory1: ApprovalFactory;
|
||||
let approvalFactory2: ApprovalFactory;
|
||||
@@ -40,8 +40,8 @@ describe('Mixins tests', () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
before(async () => {
|
||||
mixins = await TestMixinsContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestMixins,
|
||||
mixins = await CoordinatorContract.deployFrom0xArtifactAsync(
|
||||
artifacts.Coordinator,
|
||||
provider,
|
||||
txDefaults,
|
||||
exchangeAddress,
|
||||
@@ -135,6 +135,70 @@ describe('Mixins tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('decodeOrdersFromFillData', () => {
|
||||
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
|
||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||
...order,
|
||||
exchangeAddress: devConstants.NULL_ADDRESS,
|
||||
signature: devConstants.NULL_BYTES,
|
||||
}));
|
||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||
});
|
||||
}
|
||||
for (const fnName of constants.BATCH_FILL_FN_NAMES) {
|
||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||
...order,
|
||||
exchangeAddress: devConstants.NULL_ADDRESS,
|
||||
signature: devConstants.NULL_BYTES,
|
||||
}));
|
||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||
});
|
||||
}
|
||||
for (const fnName of constants.MARKET_FILL_FN_NAMES) {
|
||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
||||
const decodedSignedOrders = decodedOrders.map(order => ({
|
||||
...order,
|
||||
exchangeAddress: devConstants.NULL_ADDRESS,
|
||||
signature: devConstants.NULL_BYTES,
|
||||
}));
|
||||
expect(orders).to.deep.eq(decodedSignedOrders);
|
||||
});
|
||||
}
|
||||
for (const fnName of [constants.CANCEL_ORDER, constants.BATCH_CANCEL_ORDERS, constants.CANCEL_ORDERS_UP_TO]) {
|
||||
it(`should correctly decode the orders for ${fnName} data`, async () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
||||
const emptyArray: any[] = [];
|
||||
expect(emptyArray).to.deep.eq(decodedOrders);
|
||||
});
|
||||
}
|
||||
it('should decode an empty array for invalid data', async () => {
|
||||
const data = '0x0123456789';
|
||||
const decodedOrders = await mixins.decodeOrdersFromFillData.callAsync(data);
|
||||
const emptyArray: any[] = [];
|
||||
expect(emptyArray).to.deep.eq(decodedOrders);
|
||||
});
|
||||
it('should revert if data is less than 4 bytes long', async () => {
|
||||
const data = '0x010203';
|
||||
await expectContractCallFailedAsync(
|
||||
mixins.decodeOrdersFromFillData.callAsync(data),
|
||||
RevertReason.LibBytesGreaterOrEqualTo4LengthRequired,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Single order approvals', () => {
|
||||
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
|
||||
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
|
||||
@@ -148,15 +212,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -181,15 +236,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -203,15 +249,6 @@ describe('Mixins tests', () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTransaction(data);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
@@ -234,15 +271,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
@@ -256,15 +284,6 @@ describe('Mixins tests', () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTransaction(data);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
@@ -288,18 +307,6 @@ describe('Mixins tests', () => {
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[signature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -323,18 +330,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -358,18 +353,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
),
|
||||
RevertReason.InvalidOrigin,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -401,15 +384,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -433,15 +407,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -458,15 +423,6 @@ describe('Mixins tests', () => {
|
||||
}));
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTransaction(data);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -487,15 +443,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -521,15 +468,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.signature, approval2.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
transactionSignerAddress,
|
||||
@@ -543,15 +481,6 @@ describe('Mixins tests', () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTransaction(data);
|
||||
await mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: approvalSignerAddress1 },
|
||||
);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
approvalSignerAddress1,
|
||||
@@ -572,18 +501,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.signature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.InvalidOrigin,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -600,18 +517,6 @@ describe('Mixins tests', () => {
|
||||
const orders = [defaultOrder, defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
|
||||
const transaction = transactionFactory.newSignedTransaction(data);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[],
|
||||
[],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -636,18 +541,6 @@ describe('Mixins tests', () => {
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[signature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -677,18 +570,6 @@ describe('Mixins tests', () => {
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
|
||||
[approval1.signature, approvalSignature2],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -713,18 +594,6 @@ describe('Mixins tests', () => {
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approvalSignature2],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.InvalidApprovalSignature,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -754,18 +623,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds2,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
|
||||
[approval1.signature, approval2.signature],
|
||||
{ from: transactionSignerAddress },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -789,18 +646,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
approvalSignerAddress1,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval2.signature],
|
||||
{ from: approvalSignerAddress1 },
|
||||
),
|
||||
RevertReason.ApprovalExpired,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -824,18 +669,6 @@ describe('Mixins tests', () => {
|
||||
transactionSignerAddress,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidTransactionOrdersApproval.callAsync(
|
||||
transaction,
|
||||
orders,
|
||||
transactionSignerAddress,
|
||||
transaction.signature,
|
||||
[approvalExpirationTimeSeconds],
|
||||
[approval1.signature],
|
||||
{ from: approvalSignerAddress2 },
|
||||
),
|
||||
RevertReason.InvalidOrigin,
|
||||
);
|
||||
expectContractCallFailedAsync(
|
||||
mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
@@ -851,9 +684,9 @@ describe('Mixins tests', () => {
|
||||
}
|
||||
});
|
||||
describe('cancels', () => {
|
||||
it('should allow the tx signer to call `cancelOrders` without approval', async () => {
|
||||
it('should allow the tx signer to call `cancelOrder` without approval', async () => {
|
||||
const orders = [defaultOrder];
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
|
||||
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDER, orders);
|
||||
const transaction = transactionFactory.newSignedTransaction(data);
|
||||
await mixins.assertValidCoordinatorApprovals.callAsync(
|
||||
transaction,
|
||||
|
@@ -5,7 +5,7 @@ export const constants = {
|
||||
BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'],
|
||||
MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'],
|
||||
MATCH_ORDERS: 'matchOrders',
|
||||
CANCEL_ORDERS: 'cancelOrders',
|
||||
CANCEL_ORDER: 'cancelOrder',
|
||||
BATCH_CANCEL_ORDERS: 'batchCancelOrders',
|
||||
CANCEL_ORDERS_UP_TO: 'cancelOrdersUpTo',
|
||||
TIME_BUFFER: new BigNumber(1000),
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import { LogDecoder, txDefaults } from '@0x/contracts-test-utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts, CoordinatorRegistryContract } from '../../src';
|
||||
|
||||
@@ -26,7 +25,7 @@ export class CoordinatorRegistryWrapper {
|
||||
this._provider,
|
||||
txDefaults,
|
||||
);
|
||||
if (_.isUndefined(this._coordinatorRegistryContract)) {
|
||||
if (this._coordinatorRegistryContract === undefined) {
|
||||
throw new Error(`Failed to deploy Coordinator Registry contract.`);
|
||||
}
|
||||
return this._coordinatorRegistryContract;
|
||||
@@ -56,7 +55,7 @@ export class CoordinatorRegistryWrapper {
|
||||
return coordinatorEndpoint;
|
||||
}
|
||||
private _assertCoordinatorRegistryDeployed(): void {
|
||||
if (_.isUndefined(this._coordinatorRegistryContract)) {
|
||||
if (this._coordinatorRegistryContract === undefined) {
|
||||
throw new Error(
|
||||
'The Coordinator Registry contract was not deployed through the CoordinatorRegistryWrapper. Call `deployCoordinatorRegistryAsync` to deploy.',
|
||||
);
|
||||
|
@@ -37,7 +37,7 @@ export const exchangeDataEncoder = {
|
||||
orders[0].signature,
|
||||
orders[1].signature,
|
||||
);
|
||||
} else if (fnName === constants.CANCEL_ORDERS) {
|
||||
} else if (fnName === constants.CANCEL_ORDER) {
|
||||
data = exchangeInstance.cancelOrder.getABIEncodedTransactionData(orders[0]);
|
||||
} else if (fnName === constants.BATCH_CANCEL_ORDERS) {
|
||||
data = exchangeInstance.batchCancelOrders.getABIEncodedTransactionData(orders);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { eip712Utils, transactionHashUtils } from '@0x/order-utils';
|
||||
import { constants } from '@0x/order-utils/lib/src/constants';
|
||||
import { eip712Utils } from '@0x/order-utils';
|
||||
import { SignedZeroExTransaction } from '@0x/types';
|
||||
import { BigNumber, signTypedDataUtils } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
@@ -11,25 +10,11 @@ export const hashUtils = {
|
||||
txOrigin: string,
|
||||
approvalExpirationTimeSeconds: BigNumber,
|
||||
): Buffer {
|
||||
const domain = {
|
||||
name: constants.COORDINATOR_DOMAIN_NAME,
|
||||
version: constants.COORDINATOR_DOMAIN_VERSION,
|
||||
const typedData = eip712Utils.createCoordinatorApprovalTypedData(
|
||||
transaction,
|
||||
verifyingContractAddress,
|
||||
};
|
||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||
const approval = {
|
||||
txOrigin,
|
||||
transactionHash,
|
||||
transactionSignature: transaction.signature,
|
||||
approvalExpirationTimeSeconds: approvalExpirationTimeSeconds.toString(),
|
||||
};
|
||||
const typedData = eip712Utils.createTypedData(
|
||||
constants.COORDINATOR_APPROVAL_SCHEMA.name,
|
||||
{
|
||||
CoordinatorApproval: constants.COORDINATOR_APPROVAL_SCHEMA.parameters,
|
||||
},
|
||||
approval,
|
||||
domain,
|
||||
approvalExpirationTimeSeconds,
|
||||
);
|
||||
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
|
||||
return hashBuffer;
|
||||
|
@@ -2,11 +2,6 @@
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||
"files": [
|
||||
"generated-artifacts/Coordinator.json",
|
||||
"generated-artifacts/CoordinatorRegistry.json",
|
||||
"generated-artifacts/TestLibs.json",
|
||||
"generated-artifacts/TestMixins.json"
|
||||
],
|
||||
"files": ["generated-artifacts/Coordinator.json", "generated-artifacts/CoordinatorRegistry.json"],
|
||||
"exclude": ["./deploy/solc/solc_bin"]
|
||||
}
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "1.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"timestamp": 1553091633,
|
||||
"version": "1.0.1",
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.2 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v1.0.1 - _March 20, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "generated-artifacts",
|
||||
"contractsDir": "contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
"optimizer": { "enabled": true, "runs": 1000000 },
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc1155",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,12 +47,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,13 +67,14 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -36,8 +36,8 @@ export class Erc1155Wrapper {
|
||||
callbackData?: string,
|
||||
delegatedSpender?: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const spender = _.isUndefined(delegatedSpender) ? from : delegatedSpender;
|
||||
const callbackDataHex = _.isUndefined(callbackData) ? '0x' : callbackData;
|
||||
const spender = delegatedSpender === undefined ? from : delegatedSpender;
|
||||
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
||||
await this._erc1155Contract.safeTransferFrom.sendTransactionAsync(from, to, token, value, callbackDataHex, {
|
||||
from: spender,
|
||||
@@ -53,8 +53,8 @@ export class Erc1155Wrapper {
|
||||
callbackData?: string,
|
||||
delegatedSpender?: string,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const spender = _.isUndefined(delegatedSpender) ? from : delegatedSpender;
|
||||
const callbackDataHex = _.isUndefined(callbackData) ? '0x' : callbackData;
|
||||
const spender = delegatedSpender === undefined ? from : delegatedSpender;
|
||||
const callbackDataHex = callbackData === undefined ? '0x' : callbackData;
|
||||
const tx = await this._logDecoder.getTxWithDecodedLogsAsync(
|
||||
await this._erc1155Contract.safeBatchTransferFrom.sendTransactionAsync(
|
||||
from,
|
||||
|
@@ -1,4 +1,33 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "2.2.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Added UntransferrableDummyERC20Token",
|
||||
"pr": 1714
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.2.1 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.2.0 - _April 11, 2019_
|
||||
|
||||
* Added UntransferrableDummyERC20Token (#1714)
|
||||
|
||||
## v2.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v2.0.0 - _March 20, 2019_
|
||||
|
||||
* Upgrade contracts to Solidity 0.5.5 (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
@@ -32,6 +32,7 @@
|
||||
"src/interfaces/IEtherToken.sol",
|
||||
"test/DummyERC20Token.sol",
|
||||
"test/DummyMultipleReturnERC20Token.sol",
|
||||
"test/DummyNoReturnERC20Token.sol"
|
||||
"test/DummyNoReturnERC20Token.sol",
|
||||
"test/UntransferrableDummyERC20Token.sol"
|
||||
]
|
||||
}
|
||||
|
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 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.5.5;
|
||||
|
||||
import "./DummyERC20Token.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
contract UntransferrableDummyERC20Token is
|
||||
DummyERC20Token
|
||||
{
|
||||
constructor (
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
uint256 _decimals,
|
||||
uint256 _totalSupply
|
||||
)
|
||||
public
|
||||
DummyERC20Token(
|
||||
_name,
|
||||
_symbol,
|
||||
_decimals,
|
||||
_totalSupply
|
||||
)
|
||||
{}
|
||||
|
||||
/// @dev send `value` token to `to` from `from` on the condition it is approved by `from`
|
||||
/// @param _from The address of the sender
|
||||
/// @param _to The address of the recipient
|
||||
/// @param _value The amount of token to be transferred
|
||||
function transferFrom(
|
||||
address _from,
|
||||
address _to,
|
||||
uint256 _value
|
||||
)
|
||||
external
|
||||
returns (bool)
|
||||
{
|
||||
require(
|
||||
false,
|
||||
"TRANSFER_DISABLED"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc20",
|
||||
"version": "2.0.0",
|
||||
"version": "2.2.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,14 +68,14 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-exchange-libs": "^2.0.0",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-exchange-libs": "^2.1.2",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "2.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.2 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v2.0.0 - _March 20, 2019_
|
||||
|
||||
* Upgrade contracts to Solidity 0.5.5 (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc721",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,13 +68,13 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -1,4 +1,33 @@
|
||||
[
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Update contracts to solidity ^0.5.5 and unpin dependencies",
|
||||
"pr": 1796
|
||||
}
|
||||
],
|
||||
"timestamp": 1557507213
|
||||
},
|
||||
{
|
||||
"version": "2.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.0.0 - _May 10, 2019_
|
||||
|
||||
* Update contracts to solidity ^0.5.5 and unpin dependencies (#1796)
|
||||
|
||||
## v2.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v2.0.0 - _March 20, 2019_
|
||||
|
||||
* Do not reexport external dependencies (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./MixinWeth.sol";
|
||||
@@ -40,6 +40,7 @@ contract Forwarder is
|
||||
bytes memory _wethAssetData
|
||||
)
|
||||
public
|
||||
Ownable()
|
||||
LibConstants(
|
||||
_exchange,
|
||||
_zrxAssetData,
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/src/Ownable.sol";
|
||||
@@ -35,13 +35,13 @@ contract MixinAssets is
|
||||
|
||||
bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)"));
|
||||
|
||||
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
|
||||
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
|
||||
/// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be
|
||||
/// used to withdraw assets that were accidentally sent to this contract.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of ERC20 token to withdraw.
|
||||
function withdrawAsset(
|
||||
bytes assetData,
|
||||
bytes calldata assetData,
|
||||
uint256 amount
|
||||
)
|
||||
external
|
||||
@@ -84,7 +84,7 @@ contract MixinAssets is
|
||||
// Transfer tokens.
|
||||
// We do a raw call so we can check the success separate
|
||||
// from the return data.
|
||||
bool success = token.call(abi.encodeWithSelector(
|
||||
(bool success,) = token.call(abi.encodeWithSelector(
|
||||
ERC20_TRANSFER_SELECTOR,
|
||||
msg.sender,
|
||||
amount
|
||||
@@ -93,7 +93,7 @@ contract MixinAssets is
|
||||
success,
|
||||
"TRANSFER_FAILED"
|
||||
);
|
||||
|
||||
|
||||
// Check return data.
|
||||
// If there is no return data, we assume the token incorrectly
|
||||
// does not return a bool. In this case we expect it to revert
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibConstants.sol";
|
||||
@@ -144,6 +144,7 @@ contract MixinExchangeWrapper is
|
||||
bytes memory wethAssetData = WETH_ASSET_DATA;
|
||||
|
||||
uint256 ordersLength = orders.length;
|
||||
uint256 makerAssetFilledAmount = 0;
|
||||
for (uint256 i = 0; i != ordersLength; i++) {
|
||||
|
||||
// We assume that asset being bought by taker is the same for each order.
|
||||
@@ -175,7 +176,7 @@ contract MixinExchangeWrapper is
|
||||
addFillResults(totalFillResults, singleFillResults);
|
||||
|
||||
// Stop execution if the entire amount of makerAsset has been bought
|
||||
uint256 makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount;
|
||||
makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount;
|
||||
if (makerAssetFilledAmount >= makerAssetFillAmount) {
|
||||
break;
|
||||
}
|
||||
@@ -192,7 +193,7 @@ contract MixinExchangeWrapper is
|
||||
/// that at least zrxBuyAmount of ZRX is purchased (sometimes slightly over due to rounding issues).
|
||||
/// It is possible that a request to buy 200 ZRX will require purchasing 202 ZRX
|
||||
/// as 2 ZRX is required to purchase the 200 ZRX fee tokens. This guarantees at least 200 ZRX for future purchases.
|
||||
/// The asset being sold by taker must always be WETH.
|
||||
/// The asset being sold by taker must always be WETH.
|
||||
/// @param orders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset.
|
||||
/// @param zrxBuyAmount Desired amount of ZRX to buy.
|
||||
/// @param signatures Proofs that orders have been created by makers.
|
||||
@@ -230,7 +231,7 @@ contract MixinExchangeWrapper is
|
||||
// of the Maker. In this case we want to overestimate the amount of takerAsset.
|
||||
uint256 remainingWethSellAmount = getPartialAmountCeil(
|
||||
orders[i].takerAssetAmount,
|
||||
safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees
|
||||
safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees
|
||||
remainingZrxBuyAmount
|
||||
);
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibConstants.sol";
|
||||
@@ -58,7 +58,7 @@ contract MixinForwarderCore is
|
||||
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
|
||||
/// 5% of ETH value is reserved for paying fees to order feeRecipients (in ZRX) and forwarding contract feeRecipient (in ETH).
|
||||
/// Any ETH not spent will be refunded to sender.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param signatures Proofs that orders have been created by makers.
|
||||
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
|
||||
/// @param feeSignatures Proofs that feeOrders have been created by makers.
|
||||
@@ -70,8 +70,8 @@ contract MixinForwarderCore is
|
||||
bytes[] memory signatures,
|
||||
LibOrder.Order[] memory feeOrders,
|
||||
bytes[] memory feeSignatures,
|
||||
uint256 feePercentage,
|
||||
address feeRecipient
|
||||
uint256 feePercentage,
|
||||
address payable feeRecipient
|
||||
)
|
||||
public
|
||||
payable
|
||||
@@ -142,7 +142,7 @@ contract MixinForwarderCore is
|
||||
/// @dev Attempt to purchase makerAssetFillAmount of makerAsset by selling ETH provided with transaction.
|
||||
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
|
||||
/// Any ETH not spent will be refunded to sender.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param makerAssetFillAmount Desired amount of makerAsset to purchase.
|
||||
/// @param signatures Proofs that orders have been created by makers.
|
||||
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
|
||||
@@ -156,8 +156,8 @@ contract MixinForwarderCore is
|
||||
bytes[] memory signatures,
|
||||
LibOrder.Order[] memory feeOrders,
|
||||
bytes[] memory feeSignatures,
|
||||
uint256 feePercentage,
|
||||
address feeRecipient
|
||||
uint256 feePercentage,
|
||||
address payable feeRecipient
|
||||
)
|
||||
public
|
||||
payable
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "./libs/LibConstants.sol";
|
||||
@@ -30,7 +30,7 @@ contract MixinWeth is
|
||||
{
|
||||
/// @dev Default payabale function, this allows us to withdraw WETH
|
||||
function ()
|
||||
public
|
||||
external
|
||||
payable
|
||||
{
|
||||
require(
|
||||
@@ -60,7 +60,7 @@ contract MixinWeth is
|
||||
uint256 wethSoldExcludingFeeOrders,
|
||||
uint256 wethSoldForZrx,
|
||||
uint256 feePercentage,
|
||||
address feeRecipient
|
||||
address payable feeRecipient
|
||||
)
|
||||
internal
|
||||
{
|
||||
@@ -92,7 +92,7 @@ contract MixinWeth is
|
||||
ethFee <= wethRemaining,
|
||||
"INSUFFICIENT_ETH_REMAINING"
|
||||
);
|
||||
|
||||
|
||||
// Do nothing if no WETH remaining
|
||||
if (wethRemaining > 0) {
|
||||
// Convert remaining WETH to ETH
|
||||
|
@@ -16,18 +16,18 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
|
||||
contract IAssets {
|
||||
|
||||
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
|
||||
/// @dev Withdraws assets from this contract. The contract requires a ZRX balance in order to
|
||||
/// function optimally, and this function allows the ZRX to be withdrawn by owner. It may also be
|
||||
/// used to withdraw assets that were accidentally sent to this contract.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param amount Amount of ERC20 token to withdraw.
|
||||
function withdrawAsset(
|
||||
bytes assetData,
|
||||
bytes calldata assetData,
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IForwarderCore.sol";
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
@@ -29,7 +29,7 @@ contract IForwarderCore {
|
||||
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
|
||||
/// 5% of ETH value is reserved for paying fees to order feeRecipients (in ZRX) and forwarding contract feeRecipient (in ETH).
|
||||
/// Any ETH not spent will be refunded to sender.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param signatures Proofs that orders have been created by makers.
|
||||
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
|
||||
/// @param feeSignatures Proofs that feeOrders have been created by makers.
|
||||
@@ -41,8 +41,8 @@ contract IForwarderCore {
|
||||
bytes[] memory signatures,
|
||||
LibOrder.Order[] memory feeOrders,
|
||||
bytes[] memory feeSignatures,
|
||||
uint256 feePercentage,
|
||||
address feeRecipient
|
||||
uint256 feePercentage,
|
||||
address payable feeRecipient
|
||||
)
|
||||
public
|
||||
payable
|
||||
@@ -54,7 +54,7 @@ contract IForwarderCore {
|
||||
/// @dev Attempt to purchase makerAssetFillAmount of makerAsset by selling ETH provided with transaction.
|
||||
/// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
|
||||
/// Any ETH not spent will be refunded to sender.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
|
||||
/// @param makerAssetFillAmount Desired amount of makerAsset to purchase.
|
||||
/// @param signatures Proofs that orders have been created by makers.
|
||||
/// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
|
||||
@@ -68,8 +68,8 @@ contract IForwarderCore {
|
||||
bytes[] memory signatures,
|
||||
LibOrder.Order[] memory feeOrders,
|
||||
bytes[] memory feeSignatures,
|
||||
uint256 feePercentage,
|
||||
address feeRecipient
|
||||
uint256 feePercentage,
|
||||
address payable feeRecipient
|
||||
)
|
||||
public
|
||||
payable
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
@@ -31,10 +31,10 @@ contract LibConstants {
|
||||
bytes4 constant internal ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)"));
|
||||
bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256)"));
|
||||
uint256 constant internal MAX_UINT = 2**256 - 1;
|
||||
uint256 constant internal PERCENTAGE_DENOMINATOR = 10**18;
|
||||
uint256 constant internal PERCENTAGE_DENOMINATOR = 10**18;
|
||||
uint256 constant internal MAX_FEE_PERCENTAGE = 5 * PERCENTAGE_DENOMINATOR / 100; // 5%
|
||||
uint256 constant internal MAX_WETH_FILL_PERCENTAGE = 95 * PERCENTAGE_DENOMINATOR / 100; // 95%
|
||||
|
||||
|
||||
// solhint-disable var-name-mixedcase
|
||||
IExchange internal EXCHANGE;
|
||||
IEtherToken internal ETHER_TOKEN;
|
||||
|
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
// solhint-disable
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
|
||||
/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "../interfaces/IAssets.sol";
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
@@ -72,7 +72,7 @@ contract MExchangeWrapper {
|
||||
/// that at least zrxBuyAmount of ZRX is purchased (sometimes slightly over due to rounding issues).
|
||||
/// It is possible that a request to buy 200 ZRX will require purchasing 202 ZRX
|
||||
/// as 2 ZRX is required to purchase the 200 ZRX fee tokens. This guarantees at least 200 ZRX for future purchases.
|
||||
/// The asset being sold by taker must always be WETH.
|
||||
/// The asset being sold by taker must always be WETH.
|
||||
/// @param orders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset.
|
||||
/// @param zrxBuyAmount Desired amount of ZRX to buy.
|
||||
/// @param signatures Proofs that orders have been created by makers.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
|
||||
contract MWeth {
|
||||
@@ -35,7 +35,7 @@ contract MWeth {
|
||||
uint256 wethSoldExcludingFeeOrders,
|
||||
uint256 wethSoldForZrx,
|
||||
uint256 feePercentage,
|
||||
address feeRecipient
|
||||
address payable feeRecipient
|
||||
)
|
||||
internal;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-forwarder",
|
||||
"version": "2.0.0",
|
||||
"version": "3.0.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -46,13 +46,13 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contract-wrappers": "^8.0.4",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contract-wrappers": "^9.1.0",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -68,19 +68,19 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-asset-proxy": "^2.0.0",
|
||||
"@0x/contracts-erc20": "1.0.8",
|
||||
"@0x/contracts-erc721": "1.0.8",
|
||||
"@0x/contracts-exchange": "1.0.2",
|
||||
"@0x/contracts-exchange-libs": "1.0.2",
|
||||
"@0x/contracts-utils": "2.0.1",
|
||||
"@0x/order-utils": "^7.1.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-asset-proxy": "^2.1.2",
|
||||
"@0x/contracts-erc20": "^2.2.1",
|
||||
"@0x/contracts-erc721": "^2.1.2",
|
||||
"@0x/contracts-exchange": "^2.1.2",
|
||||
"@0x/contracts-exchange-libs": "^2.1.2",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/order-utils": "^8.0.0",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.1",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -76,8 +76,8 @@ export class ForwarderWrapper {
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = ForwarderWrapper._createOptimizedOrders(orders);
|
||||
const feeParams = ForwarderWrapper._createOptimizedZrxOrders(feeOrders);
|
||||
const feePercentage = _.isUndefined(opts.feePercentage) ? constants.ZERO_AMOUNT : opts.feePercentage;
|
||||
const feeRecipient = _.isUndefined(opts.feeRecipient) ? constants.NULL_ADDRESS : opts.feeRecipient;
|
||||
const feePercentage = opts.feePercentage === undefined ? constants.ZERO_AMOUNT : opts.feePercentage;
|
||||
const feeRecipient = opts.feeRecipient === undefined ? constants.NULL_ADDRESS : opts.feeRecipient;
|
||||
const txHash = await this._forwarderContract.marketSellOrdersWithEth.sendTransactionAsync(
|
||||
params.orders,
|
||||
params.signatures,
|
||||
@@ -99,8 +99,8 @@ export class ForwarderWrapper {
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const params = ForwarderWrapper._createOptimizedOrders(orders);
|
||||
const feeParams = ForwarderWrapper._createOptimizedZrxOrders(feeOrders);
|
||||
const feePercentage = _.isUndefined(opts.feePercentage) ? constants.ZERO_AMOUNT : opts.feePercentage;
|
||||
const feeRecipient = _.isUndefined(opts.feeRecipient) ? constants.NULL_ADDRESS : opts.feeRecipient;
|
||||
const feePercentage = opts.feePercentage === undefined ? constants.ZERO_AMOUNT : opts.feePercentage;
|
||||
const feeRecipient = opts.feeRecipient === undefined ? constants.NULL_ADDRESS : opts.feeRecipient;
|
||||
const txHash = await this._forwarderContract.marketBuyOrdersWithEth.sendTransactionAsync(
|
||||
params.orders,
|
||||
makerAssetFillAmount,
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "2.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.2 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v2.0.0 - _March 20, 2019_
|
||||
|
||||
* Upgrade contracts to Solidity 0.5.5 (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-libs",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/libs/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,14 +68,14 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/order-utils": "^7.1.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/order-utils": "^8.0.0",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "2.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.2 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v2.0.0 - _March 20, 2019_
|
||||
|
||||
* Do not reexport external dependencies (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/protocol/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,19 +68,19 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-asset-proxy": "^2.0.0",
|
||||
"@0x/contracts-erc1155": "^1.0.1",
|
||||
"@0x/contracts-erc20": "^2.0.0",
|
||||
"@0x/contracts-erc721": "^2.0.0",
|
||||
"@0x/contracts-exchange-libs": "^2.0.0",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/order-utils": "^7.1.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-asset-proxy": "^2.1.2",
|
||||
"@0x/contracts-erc1155": "^1.1.2",
|
||||
"@0x/contracts-erc20": "^2.2.1",
|
||||
"@0x/contracts-erc721": "^2.1.2",
|
||||
"@0x/contracts-exchange-libs": "^2.1.2",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/order-utils": "^8.0.0",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -437,7 +437,7 @@ export class FillOrderCombinatorialUtils {
|
||||
lazyStore: BalanceAndProxyAllowanceLazyStore,
|
||||
fillRevertReasonIfExists: RevertReason | undefined,
|
||||
): Promise<void> {
|
||||
if (!_.isUndefined(fillRevertReasonIfExists)) {
|
||||
if (fillRevertReasonIfExists !== undefined) {
|
||||
return expectTransactionFailedAsync(
|
||||
this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount }),
|
||||
fillRevertReasonIfExists,
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "3.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "3.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.2 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v3.0.0 - _March 20, 2019_
|
||||
|
||||
* Do not reexport external dependencies (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../node_modules/@0x/abi-gen-templates/contract.handlebars --partials '../../node_modules/@0x/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,13 +47,13 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contract-wrappers": "^8.0.4",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contract-wrappers": "^9.1.0",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -68,19 +69,19 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-asset-proxy": "^2.0.0",
|
||||
"@0x/contracts-erc20": "^2.0.0",
|
||||
"@0x/contracts-erc721": "^2.0.0",
|
||||
"@0x/contracts-exchange": "^2.0.0",
|
||||
"@0x/contracts-exchange-libs": "^2.0.0",
|
||||
"@0x/contracts-utils": "^3.0.0",
|
||||
"@0x/order-utils": "^7.1.0",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-asset-proxy": "^2.1.2",
|
||||
"@0x/contracts-erc20": "^2.2.1",
|
||||
"@0x/contracts-erc721": "^2.1.2",
|
||||
"@0x/contracts-exchange": "^2.1.2",
|
||||
"@0x/contracts-exchange-libs": "^2.1.2",
|
||||
"@0x/contracts-utils": "^3.1.2",
|
||||
"@0x/order-utils": "^8.0.0",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider', () => {
|
||||
provider.start();
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
after('generate coverage report', async () => {
|
||||
if (env.parseBoolean(EnvVars.SolidityCoverage)) {
|
||||
|
@@ -12,7 +12,6 @@ import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts, BalanceThresholdFilterContract } from '../../src';
|
||||
|
||||
@@ -264,7 +263,7 @@ export class BalanceThresholdWrapper {
|
||||
gas?: number,
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const signedExchangeTx = this._signerTransactionFactory.newSignedTransaction(abiEncodedExchangeTxData);
|
||||
const txOpts = _.isUndefined(gas) ? { from } : { from, gas };
|
||||
const txOpts = gas === undefined ? { from } : { from, gas };
|
||||
const txHash = await this._balanceThresholdFilter.executeTransaction.sendTransactionAsync(
|
||||
signedExchangeTx.salt,
|
||||
signedExchangeTx.signerAddress,
|
||||
|
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1557507213,
|
||||
"version": "3.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.1.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1554997931
|
||||
},
|
||||
{
|
||||
"version": "3.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Run Web3ProviderEngine without excess block polling",
|
||||
"pr": 1695
|
||||
}
|
||||
],
|
||||
"timestamp": 1553183790
|
||||
},
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.2 - _May 10, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.1 - _April 11, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.0 - _March 21, 2019_
|
||||
|
||||
* Run Web3ProviderEngine without excess block polling (#1695)
|
||||
|
||||
## v3.0.0 - _March 20, 2019_
|
||||
|
||||
* Do not reexport external dependencies (#1682)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"artifactsDir": "./generated-artifacts",
|
||||
"contractsDir": "./contracts",
|
||||
"useDockerisedSolc": true,
|
||||
"useDockerisedSolc": false,
|
||||
"isOfflineMode": false,
|
||||
"compilerSettings": {
|
||||
"evmVersion": "constantinople",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-multisig",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -24,6 +24,7 @@
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../../packages/abi-gen-templates/contract.handlebars --partials '../../packages/abi-gen-templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"fix": "tslint --fix --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -46,12 +47,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/multisig/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^2.0.7",
|
||||
"@0x/contracts-gen": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^3.1.0",
|
||||
"@0x/dev-utils": "^2.1.4",
|
||||
"@0x/sol-compiler": "^3.1.4",
|
||||
"@0x/tslint-config": "^3.0.0",
|
||||
"@0x/abi-gen": "^2.0.10",
|
||||
"@0x/contracts-gen": "^1.0.9",
|
||||
"@0x/contracts-test-utils": "^3.1.3",
|
||||
"@0x/dev-utils": "^2.2.2",
|
||||
"@0x/sol-compiler": "^3.1.7",
|
||||
"@0x/tslint-config": "^3.0.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/node": "*",
|
||||
"chai": "^4.0.1",
|
||||
@@ -67,15 +68,15 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^5.0.3",
|
||||
"@0x/contracts-asset-proxy": "^2.0.0",
|
||||
"@0x/contracts-erc20": "^2.0.0",
|
||||
"@0x/base-contract": "^5.1.0",
|
||||
"@0x/contracts-asset-proxy": "^2.1.2",
|
||||
"@0x/contracts-erc20": "^2.2.1",
|
||||
"@0x/contracts-utils": "2.0.1",
|
||||
"@0x/types": "^2.2.0",
|
||||
"@0x/typescript-typings": "^4.2.0",
|
||||
"@0x/utils": "^4.2.3",
|
||||
"@0x/web3-wrapper": "^6.0.3",
|
||||
"ethereum-types": "^2.1.1",
|
||||
"@0x/types": "^2.2.2",
|
||||
"@0x/typescript-typings": "^4.2.2",
|
||||
"@0x/utils": "^4.3.3",
|
||||
"@0x/web3-wrapper": "^6.0.6",
|
||||
"ethereum-types": "^2.1.2",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
|
||||
import { coverage, profiler, provider } from '@0x/contracts-test-utils';
|
||||
import { env, EnvVars } from '@0x/dev-utils';
|
||||
import { providerUtils } from '@0x/utils';
|
||||
|
||||
before('start web3 provider engine', () => {
|
||||
provider.start();
|
||||
before('start web3 provider', () => {
|
||||
providerUtils.startProviderEngine(provider);
|
||||
});
|
||||
|
||||
after('generate coverage report', async () => {
|
||||
|
@@ -70,7 +70,7 @@ describe('MultiSigWalletWithTimeLock', () => {
|
||||
REQUIRED_APPROVALS,
|
||||
secondsTimeLocked,
|
||||
);
|
||||
expect(_.isUndefined((multiSig as any).external_call)).to.be.equal(true);
|
||||
expect((multiSig as any).external_call === undefined).to.be.equal(true);
|
||||
});
|
||||
});
|
||||
describe('confirmTransaction', () => {
|
||||
@@ -271,7 +271,7 @@ describe('MultiSigWalletWithTimeLock', () => {
|
||||
|
||||
const blockNum = await web3Wrapper.getBlockNumberAsync();
|
||||
const blockInfo = await web3Wrapper.getBlockIfExistsAsync(blockNum);
|
||||
if (_.isUndefined(blockInfo)) {
|
||||
if (blockInfo === undefined) {
|
||||
throw new Error(`Unexpectedly failed to fetch block at #${blockNum}`);
|
||||
}
|
||||
const timestamp = new BigNumber(blockInfo.timestamp);
|
||||
|
@@ -3,7 +3,6 @@ import { LogDecoder, Web3ProviderEngine } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AssetProxyOwnerContract } from '../../generated-wrappers/asset_proxy_owner';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
@@ -23,7 +22,7 @@ export class AssetProxyOwnerWrapper {
|
||||
from: string,
|
||||
opts: { value?: BigNumber } = {},
|
||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const value = _.isUndefined(opts.value) ? new BigNumber(0) : opts.value;
|
||||
const value = opts.value === undefined ? new BigNumber(0) : opts.value;
|
||||
const txHash = await this._assetProxyOwner.submitTransaction.sendTransactionAsync(destination, value, data, {
|
||||
from,
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user