Compare commits
65 Commits
@0x/contra
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
0eff2548d5 | ||
|
93ee681204 | ||
|
d7bea98075 | ||
|
437a3b048d | ||
|
f55a9454b5 | ||
|
3b03ad0db4 | ||
|
27d679e1f1 | ||
|
1e16d59c23 | ||
|
1e7c9bbb1f | ||
|
edda1edc50 | ||
|
d1eb6279b4 | ||
|
4ace79d947 | ||
|
e5eee96487 | ||
|
907adf9145 | ||
|
c046fe6220 | ||
|
84bf20de41 | ||
|
f5a6f74d9a | ||
|
7c7fc51ccf | ||
|
fa22f6de0d | ||
|
4f41214af2 | ||
|
607b7169bc | ||
|
1253490a38 | ||
|
0a37a588e8 | ||
|
23ee108089 | ||
|
64feeeea75 | ||
|
2ebef23b8c | ||
|
cc9f43ba3b | ||
|
5f1c139176 | ||
|
9eea7de340 | ||
|
4480f84efa | ||
|
5a8b8afff1 | ||
|
67c95bc0b7 | ||
|
e70ec02be8 | ||
|
db81a94adb | ||
|
475b608338 | ||
|
27e36b112e | ||
|
f698721484 | ||
|
0c08353b2c | ||
|
a074b49732 | ||
|
43b75c7953 | ||
|
84a78eafc4 | ||
|
3c1ab889dd | ||
|
012fff46f6 | ||
|
6307ebc3a2 | ||
|
88d7e73eba | ||
|
9653eb9e70 | ||
|
ad337271d3 | ||
|
7591e99316 | ||
|
ca20df4752 | ||
|
841e4ee666 | ||
|
e2ee3414ea | ||
|
5306cc03e9 | ||
|
85f5d32de2 | ||
|
ab698cec14 | ||
|
b463a39bfa | ||
|
018e25345b | ||
|
b60fa8a7d7 | ||
|
048d8dee60 | ||
|
927fe2b58b | ||
|
89948b360c | ||
|
561b60a24d | ||
|
4f82543bdf | ||
|
3133c509f9 | ||
|
426c15692d | ||
|
8c87a77faa |
23
.readthedocs.yaml
Normal file
23
.readthedocs.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
# Required
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
# Build documentation in the docs/ directory with Sphinx
|
||||||
|
sphinx:
|
||||||
|
configuration: docs/conf.py
|
||||||
|
|
||||||
|
# Build documentation with MkDocs
|
||||||
|
#mkdocs:
|
||||||
|
# configuration: mkdocs.yml
|
||||||
|
|
||||||
|
# Optionally build your docs in additional formats such as PDF
|
||||||
|
#formats:
|
||||||
|
# - pdf
|
||||||
|
|
||||||
|
# Optionally set the version of Python and requirements required to build your docs
|
||||||
|
python:
|
||||||
|
version: 3.7
|
||||||
|
install:
|
||||||
|
- requirements: docs/requirements.txt
|
@@ -13,9 +13,11 @@
|
|||||||
"indent": ["error", 4],
|
"indent": ["error", 4],
|
||||||
"max-line-length": ["warn", 160],
|
"max-line-length": ["warn", 160],
|
||||||
"no-inline-assembly": false,
|
"no-inline-assembly": false,
|
||||||
|
"no-empty-blocks": false,
|
||||||
"quotes": ["error", "double"],
|
"quotes": ["error", "double"],
|
||||||
"separate-by-one-line-in-contract": "error",
|
"separate-by-one-line-in-contract": "error",
|
||||||
"space-after-comma": "error",
|
"space-after-comma": "error",
|
||||||
"statement-indent": "error"
|
"statement-indent": "error",
|
||||||
|
"no-empty-blocks": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,50 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "3.7.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Fix Bancor support of ETH",
|
||||||
|
"pr": 88
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1608105788
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "3.6.9",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "3.6.8",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "3.6.7",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "3.6.6",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "3.6.5",
|
"version": "3.6.5",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.7.0 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Fix Bancor support of ETH (#88)
|
||||||
|
|
||||||
|
## v3.6.9 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.6.8 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.6.7 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.6.6 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v3.6.5 - _November 13, 2020_
|
## v3.6.5 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -21,6 +21,7 @@ pragma solidity ^0.5.9;
|
|||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
|
||||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||||
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
@@ -36,6 +37,20 @@ contract BancorBridge is
|
|||||||
struct TransferState {
|
struct TransferState {
|
||||||
address bancorNetworkAddress;
|
address bancorNetworkAddress;
|
||||||
address[] path;
|
address[] path;
|
||||||
|
IEtherToken weth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Bancor ETH pseudo-address.
|
||||||
|
address constant public BANCOR_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||||
|
|
||||||
|
// solhint-disable no-empty-blocks
|
||||||
|
/// @dev Payable fallback to receive ETH from Bancor/WETH.
|
||||||
|
function ()
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
{
|
||||||
|
// Poor man's receive in 0.5.9
|
||||||
|
require(msg.data.length == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
||||||
@@ -60,7 +75,6 @@ contract BancorBridge is
|
|||||||
{
|
{
|
||||||
// hold variables to get around stack depth limitations
|
// hold variables to get around stack depth limitations
|
||||||
TransferState memory state;
|
TransferState memory state;
|
||||||
|
|
||||||
// Decode the bridge data.
|
// Decode the bridge data.
|
||||||
(
|
(
|
||||||
state.path,
|
state.path,
|
||||||
@@ -68,34 +82,42 @@ contract BancorBridge is
|
|||||||
// solhint-disable indent
|
// solhint-disable indent
|
||||||
) = abi.decode(bridgeData, (address[], address));
|
) = abi.decode(bridgeData, (address[], address));
|
||||||
// solhint-enable indent
|
// solhint-enable indent
|
||||||
|
state.weth = IEtherToken(_getWethAddress());
|
||||||
|
|
||||||
require(state.path.length > 0, "BancorBridge/PATH_MUST_EXIST");
|
require(state.path.length >= 2, "BancorBridge/PATH_LENGTH_MUST_BE_GREATER_THAN_TWO");
|
||||||
// Just transfer the tokens if they're the same.
|
|
||||||
if (state.path[0] == toTokenAddress) {
|
// Grant an allowance to the Bancor Network to spend `fromTokenAddress` token.
|
||||||
LibERC20Token.transfer(state.path[0], to, amount);
|
uint256 fromTokenBalance;
|
||||||
return BRIDGE_SUCCESS;
|
uint256 payableAmount = 0;
|
||||||
|
// If it's ETH in the path then withdraw from WETH
|
||||||
|
// The Bancor path will have ETH as the 0xeee address
|
||||||
|
// Bancor expects to be paid in ETH not WETH
|
||||||
|
if (state.path[0] == BANCOR_ETH_ADDRESS) {
|
||||||
|
fromTokenBalance = state.weth.balanceOf(address(this));
|
||||||
|
state.weth.withdraw(fromTokenBalance);
|
||||||
|
payableAmount = fromTokenBalance;
|
||||||
|
} else {
|
||||||
|
fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this));
|
||||||
|
LibERC20Token.approveIfBelow(state.path[0], state.bancorNetworkAddress, fromTokenBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise use Bancor to convert
|
|
||||||
require(state.path.length > 2, "BancorBridge/PATH_LENGTH_MUST_BE_GREATER_THAN_TWO");
|
|
||||||
require(state.path[state.path.length - 1] == toTokenAddress, "BancorBridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN");
|
|
||||||
|
|
||||||
// // Grant an allowance to the Bancor Network to spend `fromTokenAddress` token.
|
|
||||||
uint256 fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this));
|
|
||||||
LibERC20Token.approveIfBelow(state.path[0], state.bancorNetworkAddress, fromTokenBalance);
|
|
||||||
|
|
||||||
// Convert the tokens
|
// Convert the tokens
|
||||||
uint256 boughtAmount = IBancorNetwork(state.bancorNetworkAddress).convertByPath(
|
uint256 boughtAmount = IBancorNetwork(state.bancorNetworkAddress).convertByPath.value(payableAmount)(
|
||||||
state.path, // path originating with source token and terminating in destination token
|
state.path, // path originating with source token and terminating in destination token
|
||||||
fromTokenBalance, // amount of source token to trade
|
fromTokenBalance, // amount of source token to trade
|
||||||
amount, // minimum amount of destination token expected to receive
|
amount, // minimum amount of destination token expected to receive
|
||||||
to, // beneficiary
|
state.path[state.path.length-1] == BANCOR_ETH_ADDRESS ? address(this) : to, // beneficiary
|
||||||
address(0), // affiliateAccount; no fee paid
|
address(0), // affiliateAccount; no fee paid
|
||||||
0 // affiliateFee; no fee paid
|
0 // affiliateFee; no fee paid
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (state.path[state.path.length-1] == BANCOR_ETH_ADDRESS) {
|
||||||
|
state.weth.deposit.value(boughtAmount)();
|
||||||
|
state.weth.transfer(to, boughtAmount);
|
||||||
|
}
|
||||||
|
|
||||||
emit ERC20BridgeTransfer(
|
emit ERC20BridgeTransfer(
|
||||||
state.path[0], // fromTokenAddress
|
state.path[0] == BANCOR_ETH_ADDRESS ? address(state.weth) : state.path[0],
|
||||||
toTokenAddress,
|
toTokenAddress,
|
||||||
fromTokenBalance,
|
fromTokenBalance,
|
||||||
boughtAmount,
|
boughtAmount,
|
||||||
@@ -118,5 +140,5 @@ contract BancorBridge is
|
|||||||
{
|
{
|
||||||
return LEGACY_WALLET_MAGIC_VALUE;
|
return LEGACY_WALLET_MAGIC_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
136
contracts/asset-proxy/contracts/src/bridges/CryptoComBridge.sol
Normal file
136
contracts/asset-proxy/contracts/src/bridges/CryptoComBridge.sol
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||||
|
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/LibAddressArray.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
|
import "../interfaces/IUniswapV2Router01.sol";
|
||||||
|
import "../interfaces/IERC20Bridge.sol";
|
||||||
|
|
||||||
|
|
||||||
|
// solhint-disable space-after-comma
|
||||||
|
// solhint-disable not-rely-on-time
|
||||||
|
contract CryptoComBridge is
|
||||||
|
IERC20Bridge,
|
||||||
|
IWallet,
|
||||||
|
DeploymentConstants
|
||||||
|
{
|
||||||
|
struct TransferState {
|
||||||
|
address[] path;
|
||||||
|
address router;
|
||||||
|
uint256 fromTokenBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
||||||
|
/// `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress`
|
||||||
|
/// token encoded in the bridge data.
|
||||||
|
/// @param toTokenAddress The token to buy and transfer to `to`.
|
||||||
|
/// @param from The maker (this contract).
|
||||||
|
/// @param to The recipient of the bought tokens.
|
||||||
|
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
|
||||||
|
/// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress
|
||||||
|
/// @return success The magic bytes if successful.
|
||||||
|
function bridgeTransferFrom(
|
||||||
|
address toTokenAddress,
|
||||||
|
address from,
|
||||||
|
address to,
|
||||||
|
uint256 amount,
|
||||||
|
bytes calldata bridgeData
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bytes4 success)
|
||||||
|
{
|
||||||
|
// hold variables to get around stack depth limitations
|
||||||
|
TransferState memory state;
|
||||||
|
|
||||||
|
// Decode the bridge data to get the `fromTokenAddress`.
|
||||||
|
// solhint-disable indent
|
||||||
|
(state.path, state.router) = abi.decode(bridgeData, (address[], address));
|
||||||
|
// solhint-enable indent
|
||||||
|
|
||||||
|
require(state.path.length >= 2, "CryptoComBridge/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
|
||||||
|
require(state.path[state.path.length - 1] == toTokenAddress, "CryptoComBridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN");
|
||||||
|
|
||||||
|
// Just transfer the tokens if they're the same.
|
||||||
|
if (state.path[0] == toTokenAddress) {
|
||||||
|
LibERC20Token.transfer(state.path[0], to, amount);
|
||||||
|
return BRIDGE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get our balance of `fromTokenAddress` token.
|
||||||
|
state.fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this));
|
||||||
|
|
||||||
|
// Grant the SushiSwap router an allowance.
|
||||||
|
LibERC20Token.approveIfBelow(
|
||||||
|
state.path[0],
|
||||||
|
state.router,
|
||||||
|
state.fromTokenBalance
|
||||||
|
);
|
||||||
|
|
||||||
|
// Buy as much `toTokenAddress` token with `fromTokenAddress` token
|
||||||
|
// and transfer it to `to`.
|
||||||
|
IUniswapV2Router01 router = IUniswapV2Router01(state.router);
|
||||||
|
uint[] memory amounts = router.swapExactTokensForTokens(
|
||||||
|
// Sell all tokens we hold.
|
||||||
|
state.fromTokenBalance,
|
||||||
|
// Minimum buy amount.
|
||||||
|
amount,
|
||||||
|
// Convert `fromTokenAddress` to `toTokenAddress`.
|
||||||
|
state.path,
|
||||||
|
// Recipient is `to`.
|
||||||
|
to,
|
||||||
|
// Expires after this block.
|
||||||
|
block.timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
emit ERC20BridgeTransfer(
|
||||||
|
// input token
|
||||||
|
state.path[0],
|
||||||
|
// output token
|
||||||
|
toTokenAddress,
|
||||||
|
// input token amount
|
||||||
|
state.fromTokenBalance,
|
||||||
|
// output token amount
|
||||||
|
amounts[amounts.length - 1],
|
||||||
|
from,
|
||||||
|
to
|
||||||
|
);
|
||||||
|
|
||||||
|
return BRIDGE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
|
||||||
|
/// and sign for itself in orders. Always succeeds.
|
||||||
|
/// @return magicValue Success bytes, always.
|
||||||
|
function isValidSignature(
|
||||||
|
bytes32,
|
||||||
|
bytes calldata
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (bytes4 magicValue)
|
||||||
|
{
|
||||||
|
return LEGACY_WALLET_MAGIC_VALUE;
|
||||||
|
}
|
||||||
|
}
|
@@ -56,11 +56,14 @@ contract KyberBridge is
|
|||||||
uint256 constant private KYBER_RATE_BASE = 10 ** 18;
|
uint256 constant private KYBER_RATE_BASE = 10 ** 18;
|
||||||
|
|
||||||
// solhint-disable no-empty-blocks
|
// solhint-disable no-empty-blocks
|
||||||
/// @dev Payable fallback to receive ETH from Kyber.
|
/// @dev Payable fallback to receive ETH from Kyber/WETH.
|
||||||
function ()
|
function ()
|
||||||
external
|
external
|
||||||
payable
|
payable
|
||||||
{}
|
{
|
||||||
|
// Poor man's receive in 0.5.9
|
||||||
|
require(msg.data.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Callback for `IKyberBridge`. Tries to buy `amount` of
|
/// @dev Callback for `IKyberBridge`. Tries to buy `amount` of
|
||||||
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-asset-proxy",
|
"name": "@0x/contracts-asset-proxy",
|
||||||
"version": "3.6.5",
|
"version": "3.7.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CreamBridge|CurveBridge|DODOBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|SnowSwapBridge|StaticCallProxy|SushiSwapBridge|SwerveBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json",
|
"abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CreamBridge|CryptoComBridge|CurveBridge|DODOBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|SnowSwapBridge|StaticCallProxy|SushiSwapBridge|SwerveBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -51,13 +51,13 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contract-wrappers": "^13.10.0",
|
"@0x/contract-wrappers": "^13.11.0",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
@@ -79,17 +79,17 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-erc1155": "^2.1.14",
|
"@0x/contracts-erc1155": "^2.1.18",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-erc721": "^3.1.14",
|
"@0x/contracts-erc721": "^3.1.18",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -9,6 +9,7 @@ import * as BalancerBridge from '../generated-artifacts/BalancerBridge.json';
|
|||||||
import * as BancorBridge from '../generated-artifacts/BancorBridge.json';
|
import * as BancorBridge from '../generated-artifacts/BancorBridge.json';
|
||||||
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
|
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
|
||||||
import * as CreamBridge from '../generated-artifacts/CreamBridge.json';
|
import * as CreamBridge from '../generated-artifacts/CreamBridge.json';
|
||||||
|
import * as CryptoComBridge from '../generated-artifacts/CryptoComBridge.json';
|
||||||
import * as CurveBridge from '../generated-artifacts/CurveBridge.json';
|
import * as CurveBridge from '../generated-artifacts/CurveBridge.json';
|
||||||
import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json';
|
import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json';
|
||||||
import * as DODOBridge from '../generated-artifacts/DODOBridge.json';
|
import * as DODOBridge from '../generated-artifacts/DODOBridge.json';
|
||||||
@@ -77,6 +78,7 @@ export const artifacts = {
|
|||||||
BancorBridge: BancorBridge as ContractArtifact,
|
BancorBridge: BancorBridge as ContractArtifact,
|
||||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||||
CreamBridge: CreamBridge as ContractArtifact,
|
CreamBridge: CreamBridge as ContractArtifact,
|
||||||
|
CryptoComBridge: CryptoComBridge as ContractArtifact,
|
||||||
CurveBridge: CurveBridge as ContractArtifact,
|
CurveBridge: CurveBridge as ContractArtifact,
|
||||||
DODOBridge: DODOBridge as ContractArtifact,
|
DODOBridge: DODOBridge as ContractArtifact,
|
||||||
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
||||||
|
@@ -7,6 +7,7 @@ export * from '../generated-wrappers/balancer_bridge';
|
|||||||
export * from '../generated-wrappers/bancor_bridge';
|
export * from '../generated-wrappers/bancor_bridge';
|
||||||
export * from '../generated-wrappers/chai_bridge';
|
export * from '../generated-wrappers/chai_bridge';
|
||||||
export * from '../generated-wrappers/cream_bridge';
|
export * from '../generated-wrappers/cream_bridge';
|
||||||
|
export * from '../generated-wrappers/crypto_com_bridge';
|
||||||
export * from '../generated-wrappers/curve_bridge';
|
export * from '../generated-wrappers/curve_bridge';
|
||||||
export * from '../generated-wrappers/d_o_d_o_bridge';
|
export * from '../generated-wrappers/d_o_d_o_bridge';
|
||||||
export * from '../generated-wrappers/dex_forwarder_bridge';
|
export * from '../generated-wrappers/dex_forwarder_bridge';
|
||||||
|
@@ -9,6 +9,7 @@ import * as BalancerBridge from '../test/generated-artifacts/BalancerBridge.json
|
|||||||
import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json';
|
import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json';
|
||||||
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
|
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
|
||||||
import * as CreamBridge from '../test/generated-artifacts/CreamBridge.json';
|
import * as CreamBridge from '../test/generated-artifacts/CreamBridge.json';
|
||||||
|
import * as CryptoComBridge from '../test/generated-artifacts/CryptoComBridge.json';
|
||||||
import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json';
|
import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json';
|
||||||
import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json';
|
import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json';
|
||||||
import * as DODOBridge from '../test/generated-artifacts/DODOBridge.json';
|
import * as DODOBridge from '../test/generated-artifacts/DODOBridge.json';
|
||||||
@@ -77,6 +78,7 @@ export const artifacts = {
|
|||||||
BancorBridge: BancorBridge as ContractArtifact,
|
BancorBridge: BancorBridge as ContractArtifact,
|
||||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||||
CreamBridge: CreamBridge as ContractArtifact,
|
CreamBridge: CreamBridge as ContractArtifact,
|
||||||
|
CryptoComBridge: CryptoComBridge as ContractArtifact,
|
||||||
CurveBridge: CurveBridge as ContractArtifact,
|
CurveBridge: CurveBridge as ContractArtifact,
|
||||||
DODOBridge: DODOBridge as ContractArtifact,
|
DODOBridge: DODOBridge as ContractArtifact,
|
||||||
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
||||||
|
@@ -12,13 +12,11 @@ import { DecodedLogs } from 'ethereum-types';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts } from './artifacts';
|
import { artifacts } from './artifacts';
|
||||||
|
|
||||||
import { TestBancorBridgeContract } from './generated-wrappers/test_bancor_bridge';
|
import { TestBancorBridgeContract } from './generated-wrappers/test_bancor_bridge';
|
||||||
import {
|
import {
|
||||||
TestBancorBridgeConvertByPathInputEventArgs as ConvertByPathArgs,
|
TestBancorBridgeConvertByPathInputEventArgs as ConvertByPathArgs,
|
||||||
TestBancorBridgeEvents as ContractEvents,
|
TestBancorBridgeEvents as ContractEvents,
|
||||||
TestBancorBridgeTokenApproveEventArgs as TokenApproveArgs,
|
TestBancorBridgeTokenApproveEventArgs as TokenApproveArgs,
|
||||||
TestBancorBridgeTokenTransferEventArgs as TokenTransferArgs,
|
|
||||||
} from './wrappers';
|
} from './wrappers';
|
||||||
|
|
||||||
blockchainTests.resets('Bancor unit tests', env => {
|
blockchainTests.resets('Bancor unit tests', env => {
|
||||||
@@ -128,24 +126,6 @@ blockchainTests.resets('Bancor unit tests', env => {
|
|||||||
expect(result).to.eq(AssetProxyId.ERC20Bridge);
|
expect(result).to.eq(AssetProxyId.ERC20Bridge);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('performs transfer when both tokens are the same', async () => {
|
|
||||||
const createTokenFn = testContract.createToken(constants.NULL_ADDRESS);
|
|
||||||
const tokenAddress = await createTokenFn.callAsync();
|
|
||||||
await createTokenFn.awaitTransactionSuccessAsync();
|
|
||||||
|
|
||||||
const { opts, result, logs } = await transferFromAsync({
|
|
||||||
tokenAddressesPath: [tokenAddress, tokenAddress],
|
|
||||||
});
|
|
||||||
expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id');
|
|
||||||
const transfers = filterLogsToArguments<TokenTransferArgs>(logs, ContractEvents.TokenTransfer);
|
|
||||||
|
|
||||||
expect(transfers.length).to.eq(1);
|
|
||||||
expect(transfers[0].token).to.eq(tokenAddress, 'input token address');
|
|
||||||
expect(transfers[0].from).to.eq(testContract.address);
|
|
||||||
expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address');
|
|
||||||
expect(transfers[0].amount).to.bignumber.eq(opts.amount, 'amount');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('token -> token', async () => {
|
describe('token -> token', async () => {
|
||||||
it('calls BancorNetwork.convertByPath()', async () => {
|
it('calls BancorNetwork.convertByPath()', async () => {
|
||||||
const { opts, result, logs } = await transferFromAsync();
|
const { opts, result, logs } = await transferFromAsync();
|
||||||
|
@@ -7,6 +7,7 @@ export * from '../test/generated-wrappers/balancer_bridge';
|
|||||||
export * from '../test/generated-wrappers/bancor_bridge';
|
export * from '../test/generated-wrappers/bancor_bridge';
|
||||||
export * from '../test/generated-wrappers/chai_bridge';
|
export * from '../test/generated-wrappers/chai_bridge';
|
||||||
export * from '../test/generated-wrappers/cream_bridge';
|
export * from '../test/generated-wrappers/cream_bridge';
|
||||||
|
export * from '../test/generated-wrappers/crypto_com_bridge';
|
||||||
export * from '../test/generated-wrappers/curve_bridge';
|
export * from '../test/generated-wrappers/curve_bridge';
|
||||||
export * from '../test/generated-wrappers/d_o_d_o_bridge';
|
export * from '../test/generated-wrappers/d_o_d_o_bridge';
|
||||||
export * from '../test/generated-wrappers/dex_forwarder_bridge';
|
export * from '../test/generated-wrappers/dex_forwarder_bridge';
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
"generated-artifacts/BancorBridge.json",
|
"generated-artifacts/BancorBridge.json",
|
||||||
"generated-artifacts/ChaiBridge.json",
|
"generated-artifacts/ChaiBridge.json",
|
||||||
"generated-artifacts/CreamBridge.json",
|
"generated-artifacts/CreamBridge.json",
|
||||||
|
"generated-artifacts/CryptoComBridge.json",
|
||||||
"generated-artifacts/CurveBridge.json",
|
"generated-artifacts/CurveBridge.json",
|
||||||
"generated-artifacts/DODOBridge.json",
|
"generated-artifacts/DODOBridge.json",
|
||||||
"generated-artifacts/DexForwarderBridge.json",
|
"generated-artifacts/DexForwarderBridge.json",
|
||||||
@@ -65,6 +66,7 @@
|
|||||||
"test/generated-artifacts/BancorBridge.json",
|
"test/generated-artifacts/BancorBridge.json",
|
||||||
"test/generated-artifacts/ChaiBridge.json",
|
"test/generated-artifacts/ChaiBridge.json",
|
||||||
"test/generated-artifacts/CreamBridge.json",
|
"test/generated-artifacts/CreamBridge.json",
|
||||||
|
"test/generated-artifacts/CryptoComBridge.json",
|
||||||
"test/generated-artifacts/CurveBridge.json",
|
"test/generated-artifacts/CurveBridge.json",
|
||||||
"test/generated-artifacts/DODOBridge.json",
|
"test/generated-artifacts/DODOBridge.json",
|
||||||
"test/generated-artifacts/DexForwarderBridge.json",
|
"test/generated-artifacts/DexForwarderBridge.json",
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "1.1.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "1.1.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "1.1.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "1.1.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "1.1.14",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "1.1.13",
|
"version": "1.1.13",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.1.18 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.1.17 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.1.16 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.1.15 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.1.14 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v1.1.13 - _November 13, 2020_
|
## v1.1.13 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-broker",
|
"name": "@0x/contracts-broker",
|
||||||
"version": "1.1.13",
|
"version": "1.1.18",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -51,20 +51,20 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-erc721": "^3.1.14",
|
"@0x/contracts-erc721": "^3.1.18",
|
||||||
"@0x/contracts-exchange": "^3.2.14",
|
"@0x/contracts-exchange": "^3.2.19",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -84,11 +84,11 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"ethereum-types": "^3.3.3"
|
"ethereum-types": "^3.4.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "3.1.19",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "3.1.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "3.1.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "3.1.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "3.1.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "3.1.14",
|
"version": "3.1.14",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.1.19 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v3.1.14 - _November 13, 2020_
|
## v3.1.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-coordinator",
|
"name": "@0x/contracts-coordinator",
|
||||||
"version": "3.1.14",
|
"version": "3.1.19",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,17 +52,17 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-dev-utils": "^1.3.12",
|
"@0x/contracts-dev-utils": "^1.3.17",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -82,17 +82,17 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.17",
|
"@0x/assert": "^3.0.19",
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contract-addresses": "^5.3.0",
|
"@0x/contract-addresses": "^5.6.0",
|
||||||
"@0x/contracts-exchange": "^3.2.14",
|
"@0x/contracts-exchange": "^3.2.19",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/json-schemas": "^5.3.3",
|
"@0x/json-schemas": "^5.3.4",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"http-status-codes": "^1.3.2"
|
"http-status-codes": "^1.3.2"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "1.3.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "1.3.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "1.3.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "1.3.14",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "1.3.13",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "1.3.12",
|
"version": "1.3.12",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.3.17 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.3.16 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.3.15 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.3.14 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.3.13 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v1.3.12 - _November 13, 2020_
|
## v1.3.12 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-dev-utils",
|
"name": "@0x/contracts-dev-utils",
|
||||||
"version": "1.3.12",
|
"version": "1.3.17",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -41,18 +41,18 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/assert": "^3.0.17",
|
"@0x/assert": "^3.0.19",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"ethers": "~4.0.4",
|
"ethers": "~4.0.4",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@types/node": "12.12.54"
|
"@types/node": "12.12.54"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -1,4 +1,40 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "2.1.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "2.1.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "2.1.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "2.1.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "2.1.14",
|
"version": "2.1.14",
|
||||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v2.1.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.1.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.1.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.1.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v2.1.14 - _November 13, 2020_
|
## v2.1.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-erc1155",
|
"name": "@0x/contracts-erc1155",
|
||||||
"version": "2.1.14",
|
"version": "2.1.18",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,15 +52,15 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"make-promises-safe": "^1.1.0",
|
"make-promises-safe": "^1.1.0",
|
||||||
"mocha": "^6.2.0",
|
"mocha": "^6.2.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
@@ -80,10 +80,10 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -1,4 +1,40 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "3.2.12",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "3.2.11",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "3.2.10",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "3.2.9",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "3.2.8",
|
"version": "3.2.8",
|
||||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.2.12 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.11 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.10 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.9 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v3.2.8 - _November 13, 2020_
|
## v3.2.8 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-erc20",
|
"name": "@0x/contracts-erc20",
|
||||||
"version": "3.2.8",
|
"version": "3.2.12",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -51,18 +51,18 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"make-promises-safe": "^1.1.0",
|
"make-promises-safe": "^1.1.0",
|
||||||
"mocha": "^6.2.0",
|
"mocha": "^6.2.0",
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11"
|
"@0x/base-contract": "^6.2.14"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,40 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "3.1.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "3.1.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "3.1.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "3.1.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "3.1.14",
|
"version": "3.1.14",
|
||||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.1.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.1.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v3.1.14 - _November 13, 2020_
|
## v3.1.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-erc721",
|
"name": "@0x/contracts-erc721",
|
||||||
"version": "3.1.14",
|
"version": "3.1.18",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,18 +52,18 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"make-promises-safe": "^1.1.0",
|
"make-promises-safe": "^1.1.0",
|
||||||
"mocha": "^6.2.0",
|
"mocha": "^6.2.0",
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11"
|
"@0x/base-contract": "^6.2.14"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "4.2.19",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "4.2.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "4.2.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "4.2.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "4.2.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "4.2.14",
|
"version": "4.2.14",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v4.2.19 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.2.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.2.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.2.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.2.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v4.2.14 - _November 13, 2020_
|
## v4.2.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-exchange-forwarder",
|
"name": "@0x/contracts-exchange-forwarder",
|
||||||
"version": "4.2.14",
|
"version": "4.2.19",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,25 +52,25 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-dev-utils": "^1.3.12",
|
"@0x/contracts-dev-utils": "^1.3.17",
|
||||||
"@0x/contracts-erc1155": "^2.1.14",
|
"@0x/contracts-erc1155": "^2.1.18",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-erc721": "^3.1.14",
|
"@0x/contracts-erc721": "^3.1.18",
|
||||||
"@0x/contracts-exchange": "^3.2.14",
|
"@0x/contracts-exchange": "^3.2.19",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -90,9 +90,9 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"ethereum-types": "^3.3.3"
|
"ethereum-types": "^3.4.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,40 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "4.3.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "4.3.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "4.3.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "4.3.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "4.3.14",
|
"version": "4.3.14",
|
||||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v4.3.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.3.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.3.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.3.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v4.3.14 - _November 13, 2020_
|
## v4.3.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-exchange-libs",
|
"name": "@0x/contracts-exchange-libs",
|
||||||
"version": "4.3.14",
|
"version": "4.3.18",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,14 +52,14 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/subproviders": "^6.1.9",
|
"@0x/subproviders": "^6.2.3",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -80,14 +80,14 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"ethereum-types": "^3.3.3"
|
"ethereum-types": "^3.4.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "3.2.19",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "3.2.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "3.2.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "3.2.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "3.2.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "3.2.14",
|
"version": "3.2.14",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.2.19 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.2.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v3.2.14 - _November 13, 2020_
|
## v3.2.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-exchange",
|
"name": "@0x/contracts-exchange",
|
||||||
"version": "3.2.14",
|
"version": "3.2.19",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,21 +52,21 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-multisig": "^4.1.14",
|
"@0x/contracts-multisig": "^4.1.19",
|
||||||
"@0x/contracts-staking": "^2.0.21",
|
"@0x/contracts-staking": "^2.0.26",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"ethereumjs-util": "^5.1.1",
|
"ethereumjs-util": "^5.1.1",
|
||||||
"js-combinatorics": "^0.5.3",
|
"js-combinatorics": "^0.5.3",
|
||||||
"make-promises-safe": "^1.1.0",
|
"make-promises-safe": "^1.1.0",
|
||||||
@@ -88,13 +88,13 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-dev-utils": "^1.3.12",
|
"@0x/contracts-dev-utils": "^1.3.17",
|
||||||
"@0x/contracts-erc1155": "^2.1.14",
|
"@0x/contracts-erc1155": "^2.1.18",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-erc721": "^3.1.14",
|
"@0x/contracts-erc721": "^3.1.18",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "6.2.13",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "6.2.12",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "6.2.11",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "6.2.10",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "6.2.9",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "6.2.8",
|
"version": "6.2.8",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v6.2.13 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v6.2.12 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v6.2.11 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v6.2.10 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v6.2.9 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v6.2.8 - _November 13, 2020_
|
## v6.2.8 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-extensions",
|
"name": "@0x/contracts-extensions",
|
||||||
"version": "6.2.8",
|
"version": "6.2.13",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,23 +52,23 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-dev-utils": "^1.3.12",
|
"@0x/contracts-dev-utils": "^1.3.17",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-erc721": "^3.1.14",
|
"@0x/contracts-erc721": "^3.1.18",
|
||||||
"@0x/contracts-exchange": "^3.2.14",
|
"@0x/contracts-exchange": "^3.2.19",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -90,10 +90,10 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"ethereum-types": "^3.3.3"
|
"ethereum-types": "^3.4.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "2.7.10",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605320370,
|
||||||
|
"version": "2.7.9",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "2.7.8",
|
"version": "2.7.8",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v2.7.10 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.7.9 - _November 14, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v2.7.8 - _November 13, 2020_
|
## v2.7.8 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
|
||||||
|
import "@0x/contracts-zero-ex/contracts/test/TestFixinProtocolFees.sol";
|
||||||
|
import "@0x/contracts-zero-ex/contracts/src/external/FeeCollectorController.sol";
|
||||||
|
|
||||||
|
|
||||||
|
contract TestFixinProtocolFeesIntegration is TestFixinProtocolFees {
|
||||||
|
constructor(
|
||||||
|
IEtherTokenV06 weth,
|
||||||
|
IStaking staking,
|
||||||
|
uint32 protocolFeeMultiplier
|
||||||
|
)
|
||||||
|
public
|
||||||
|
TestFixinProtocolFees(
|
||||||
|
weth,
|
||||||
|
staking,
|
||||||
|
new FeeCollectorController(weth, staking),
|
||||||
|
protocolFeeMultiplier
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
}
|
110
contracts/integrations/contracts/test/TestStaking.sol
Normal file
110
contracts/integrations/contracts/test/TestStaking.sol
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-staking/contracts/src/Staking.sol";
|
||||||
|
|
||||||
|
|
||||||
|
contract TestStaking is
|
||||||
|
Staking
|
||||||
|
{
|
||||||
|
IEtherToken public testWeth;
|
||||||
|
|
||||||
|
struct TestPool {
|
||||||
|
uint96 operatorStake;
|
||||||
|
uint96 membersStake;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping(bytes32 => TestPool) private _testPools;
|
||||||
|
|
||||||
|
constructor(address exchangeAddress, IEtherToken _testWeth) public {
|
||||||
|
testWeth = _testWeth;
|
||||||
|
|
||||||
|
_addAuthorizedAddress(msg.sender);
|
||||||
|
init();
|
||||||
|
validExchanges[exchangeAddress] = true;
|
||||||
|
_removeAuthorizedAddressAtIndex(msg.sender, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function advanceEpoch()
|
||||||
|
external
|
||||||
|
{
|
||||||
|
currentEpoch += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Create a test pool.
|
||||||
|
function createTestPool(
|
||||||
|
bytes32 poolId,
|
||||||
|
uint96 operatorStake,
|
||||||
|
uint96 membersStake
|
||||||
|
)
|
||||||
|
external
|
||||||
|
{
|
||||||
|
TestPool storage pool = _testPools[poolId];
|
||||||
|
pool.operatorStake = operatorStake;
|
||||||
|
pool.membersStake = membersStake;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAggregatedStatsForCurrentEpoch()
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (IStructs.AggregatedStats memory)
|
||||||
|
{
|
||||||
|
return aggregatedStatsByEpoch[currentEpoch];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Overridden to use test pools.
|
||||||
|
function getTotalStakeDelegatedToPool(bytes32 poolId)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (IStructs.StoredBalance memory balance)
|
||||||
|
{
|
||||||
|
TestPool memory pool = _testPools[poolId];
|
||||||
|
uint96 stake = pool.operatorStake + pool.membersStake;
|
||||||
|
return IStructs.StoredBalance({
|
||||||
|
currentEpoch: currentEpoch.downcastToUint64(),
|
||||||
|
currentEpochBalance: stake,
|
||||||
|
nextEpochBalance: stake
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Overridden to use test pools.
|
||||||
|
function getStakeDelegatedToPoolByOwner(address, bytes32 poolId)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (IStructs.StoredBalance memory balance)
|
||||||
|
{
|
||||||
|
TestPool memory pool = _testPools[poolId];
|
||||||
|
return IStructs.StoredBalance({
|
||||||
|
currentEpoch: currentEpoch.downcastToUint64(),
|
||||||
|
currentEpochBalance: pool.operatorStake,
|
||||||
|
nextEpochBalance: pool.operatorStake
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWethContract()
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (IEtherToken wethContract)
|
||||||
|
{
|
||||||
|
return testWeth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
|
||||||
|
import "@0x/contracts-zero-ex/contracts/test/TestWeth.sol";
|
||||||
|
|
||||||
|
|
||||||
|
contract TestWethIntegration is TestWeth {}
|
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-integrations",
|
"name": "@0x/contracts-integrations",
|
||||||
"version": "2.7.8",
|
"version": "2.7.16",
|
||||||
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -38,7 +39,7 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"publicInterfaceContracts": "TestFramework",
|
"publicInterfaceContracts": "TestFramework",
|
||||||
"abis": "./test/generated-artifacts/@(ChainlinkStopLimit|IChainlinkAggregator|TestChainlinkAggregator|TestContractWrapper|TestDydxUser|TestEth2Dai|TestEth2DaiBridge|TestFramework|TestMainnetAggregatorFills|TestSignatureValidationWallet|TestUniswapBridge|TestUniswapExchange|TestUniswapExchangeFactory).json",
|
"abis": "./test/generated-artifacts/@(ChainlinkStopLimit|IChainlinkAggregator|TestChainlinkAggregator|TestContractWrapper|TestDydxUser|TestEth2Dai|TestEth2DaiBridge|TestFixinProtocolFeesIntegration|TestFramework|TestMainnetAggregatorFills|TestSignatureValidationWallet|TestStaking|TestUniswapBridge|TestUniswapExchange|TestUniswapExchangeFactory|TestWethIntegration).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -51,24 +52,25 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contract-addresses": "^5.3.0",
|
"@0x/contract-addresses": "^5.6.0",
|
||||||
"@0x/contract-wrappers": "^13.10.0",
|
"@0x/contract-wrappers": "^13.11.0",
|
||||||
"@0x/contracts-broker": "^1.1.13",
|
"@0x/contracts-broker": "^1.1.18",
|
||||||
"@0x/contracts-coordinator": "^3.1.14",
|
"@0x/contracts-coordinator": "^3.1.19",
|
||||||
"@0x/contracts-dev-utils": "^1.3.12",
|
"@0x/contracts-dev-utils": "^1.3.17",
|
||||||
"@0x/contracts-exchange-forwarder": "^4.2.14",
|
"@0x/contracts-exchange-forwarder": "^4.2.19",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/contracts-extensions": "^6.2.8",
|
"@0x/contracts-extensions": "^6.2.13",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/coordinator-server": "^1.0.5",
|
"@0x/coordinator-server": "^1.0.5",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/migrations": "^6.5.0",
|
"@0x/migrations": "^6.5.5",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/protocol-utils": "^1.0.1",
|
||||||
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@azure/core-asynciterator-polyfill": "^1.0.0",
|
"@azure/core-asynciterator-polyfill": "^1.0.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
@@ -91,22 +93,22 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/asset-swapper": "^5.1.0",
|
"@0x/asset-swapper": "^5.5.0",
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-erc1155": "^2.1.14",
|
"@0x/contracts-erc1155": "^2.1.18",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-erc721": "^3.1.14",
|
"@0x/contracts-erc721": "^3.1.18",
|
||||||
"@0x/contracts-exchange": "^3.2.14",
|
"@0x/contracts-exchange": "^3.2.19",
|
||||||
"@0x/contracts-multisig": "^4.1.14",
|
"@0x/contracts-multisig": "^4.1.19",
|
||||||
"@0x/contracts-staking": "^2.0.21",
|
"@0x/contracts-staking": "^2.0.26",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-zero-ex": "^0.9.0",
|
"@0x/contracts-zero-ex": "^0.13.0",
|
||||||
"@0x/subproviders": "^6.1.9",
|
"@0x/subproviders": "^6.2.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"ethereumjs-util": "^6.2.0",
|
"ethereumjs-util": "^6.2.0",
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
|
@@ -12,12 +12,15 @@ import * as TestContractWrapper from '../test/generated-artifacts/TestContractWr
|
|||||||
import * as TestDydxUser from '../test/generated-artifacts/TestDydxUser.json';
|
import * as TestDydxUser from '../test/generated-artifacts/TestDydxUser.json';
|
||||||
import * as TestEth2Dai from '../test/generated-artifacts/TestEth2Dai.json';
|
import * as TestEth2Dai from '../test/generated-artifacts/TestEth2Dai.json';
|
||||||
import * as TestEth2DaiBridge from '../test/generated-artifacts/TestEth2DaiBridge.json';
|
import * as TestEth2DaiBridge from '../test/generated-artifacts/TestEth2DaiBridge.json';
|
||||||
|
import * as TestFixinProtocolFeesIntegration from '../test/generated-artifacts/TestFixinProtocolFeesIntegration.json';
|
||||||
import * as TestFramework from '../test/generated-artifacts/TestFramework.json';
|
import * as TestFramework from '../test/generated-artifacts/TestFramework.json';
|
||||||
import * as TestMainnetAggregatorFills from '../test/generated-artifacts/TestMainnetAggregatorFills.json';
|
import * as TestMainnetAggregatorFills from '../test/generated-artifacts/TestMainnetAggregatorFills.json';
|
||||||
import * as TestSignatureValidationWallet from '../test/generated-artifacts/TestSignatureValidationWallet.json';
|
import * as TestSignatureValidationWallet from '../test/generated-artifacts/TestSignatureValidationWallet.json';
|
||||||
|
import * as TestStaking from '../test/generated-artifacts/TestStaking.json';
|
||||||
import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridge.json';
|
import * as TestUniswapBridge from '../test/generated-artifacts/TestUniswapBridge.json';
|
||||||
import * as TestUniswapExchange from '../test/generated-artifacts/TestUniswapExchange.json';
|
import * as TestUniswapExchange from '../test/generated-artifacts/TestUniswapExchange.json';
|
||||||
import * as TestUniswapExchangeFactory from '../test/generated-artifacts/TestUniswapExchangeFactory.json';
|
import * as TestUniswapExchangeFactory from '../test/generated-artifacts/TestUniswapExchangeFactory.json';
|
||||||
|
import * as TestWethIntegration from '../test/generated-artifacts/TestWethIntegration.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
ChainlinkStopLimit: ChainlinkStopLimit as ContractArtifact,
|
ChainlinkStopLimit: ChainlinkStopLimit as ContractArtifact,
|
||||||
IChainlinkAggregator: IChainlinkAggregator as ContractArtifact,
|
IChainlinkAggregator: IChainlinkAggregator as ContractArtifact,
|
||||||
@@ -26,10 +29,13 @@ export const artifacts = {
|
|||||||
TestDydxUser: TestDydxUser as ContractArtifact,
|
TestDydxUser: TestDydxUser as ContractArtifact,
|
||||||
TestEth2Dai: TestEth2Dai as ContractArtifact,
|
TestEth2Dai: TestEth2Dai as ContractArtifact,
|
||||||
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
|
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
|
||||||
|
TestFixinProtocolFeesIntegration: TestFixinProtocolFeesIntegration as ContractArtifact,
|
||||||
TestFramework: TestFramework as ContractArtifact,
|
TestFramework: TestFramework as ContractArtifact,
|
||||||
TestMainnetAggregatorFills: TestMainnetAggregatorFills as ContractArtifact,
|
TestMainnetAggregatorFills: TestMainnetAggregatorFills as ContractArtifact,
|
||||||
TestSignatureValidationWallet: TestSignatureValidationWallet as ContractArtifact,
|
TestSignatureValidationWallet: TestSignatureValidationWallet as ContractArtifact,
|
||||||
|
TestStaking: TestStaking as ContractArtifact,
|
||||||
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
|
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
|
||||||
TestUniswapExchange: TestUniswapExchange as ContractArtifact,
|
TestUniswapExchange: TestUniswapExchange as ContractArtifact,
|
||||||
TestUniswapExchangeFactory: TestUniswapExchangeFactory as ContractArtifact,
|
TestUniswapExchangeFactory: TestUniswapExchangeFactory as ContractArtifact,
|
||||||
|
TestWethIntegration: TestWethIntegration as ContractArtifact,
|
||||||
};
|
};
|
||||||
|
@@ -6,24 +6,31 @@ import {
|
|||||||
artifacts as exchangeProxyArtifacts,
|
artifacts as exchangeProxyArtifacts,
|
||||||
IZeroExContract,
|
IZeroExContract,
|
||||||
LogMetadataTransformerContract,
|
LogMetadataTransformerContract,
|
||||||
signCallData,
|
|
||||||
} from '@0x/contracts-zero-ex';
|
} from '@0x/contracts-zero-ex';
|
||||||
import { migrateOnceAsync } from '@0x/migrations';
|
import { migrateOnceAsync } from '@0x/migrations';
|
||||||
|
import { assetDataUtils, signatureUtils, SignedExchangeProxyMetaTransaction } from '@0x/order-utils';
|
||||||
import {
|
import {
|
||||||
assetDataUtils,
|
|
||||||
encodeFillQuoteTransformerData,
|
encodeFillQuoteTransformerData,
|
||||||
encodePayTakerTransformerData,
|
encodePayTakerTransformerData,
|
||||||
ETH_TOKEN_ADDRESS,
|
ETH_TOKEN_ADDRESS,
|
||||||
FillQuoteTransformerSide,
|
FillQuoteTransformerSide,
|
||||||
findTransformerNonce,
|
findTransformerNonce,
|
||||||
signatureUtils,
|
Signature,
|
||||||
SignedExchangeProxyMetaTransaction,
|
} from '@0x/protocol-utils';
|
||||||
} from '@0x/order-utils';
|
|
||||||
import { AssetProxyId, Order, SignedOrder } from '@0x/types';
|
import { AssetProxyId, Order, SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, hexUtils, ZeroExRevertErrors } from '@0x/utils';
|
import { BigNumber, hexUtils } from '@0x/utils';
|
||||||
import * as ethjs from 'ethereumjs-util';
|
import * as ethjs from 'ethereumjs-util';
|
||||||
|
|
||||||
const { MAX_UINT256, NULL_ADDRESS, NULL_BYTES, NULL_BYTES32, ZERO_AMOUNT } = constants;
|
const { MAX_UINT256, NULL_ADDRESS, NULL_BYTES, ZERO_AMOUNT } = constants;
|
||||||
|
|
||||||
|
function sigstruct(signature: string): Signature {
|
||||||
|
return {
|
||||||
|
v: parseInt(hexUtils.slice(signature, 0, 1), 16),
|
||||||
|
signatureType: parseInt(hexUtils.slice(signature, 65, 66), 16),
|
||||||
|
r: hexUtils.slice(signature, 1, 33),
|
||||||
|
s: hexUtils.slice(signature, 33, 65),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
||||||
const quoteSignerKey = hexUtils.random();
|
const quoteSignerKey = hexUtils.random();
|
||||||
@@ -188,21 +195,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
.getABIEncodedTransactionData();
|
.getABIEncodedTransactionData();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSignedSwapData(swap: SwapInfo, signerKey?: string): string {
|
|
||||||
return signCallData(
|
|
||||||
zeroEx
|
|
||||||
.transformERC20(
|
|
||||||
swap.inputTokenAddress,
|
|
||||||
swap.outputTokenAddress,
|
|
||||||
swap.inputTokenAmount,
|
|
||||||
swap.minOutputTokenAmount,
|
|
||||||
swap.transformations,
|
|
||||||
)
|
|
||||||
.getABIEncodedTransactionData(),
|
|
||||||
signerKey ? signerKey : quoteSignerKey,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createMetaTransactionAsync(
|
async function createMetaTransactionAsync(
|
||||||
data: string,
|
data: string,
|
||||||
value: BigNumber,
|
value: BigNumber,
|
||||||
@@ -232,15 +224,13 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('can call `transformERC20()` with signed calldata and no relayer fee', async () => {
|
it('can call `transformERC20()` with calldata and no relayer fee', async () => {
|
||||||
const swap = await generateSwapAsync();
|
const swap = await generateSwapAsync();
|
||||||
const callDataHash = hexUtils.hash(getSwapData(swap));
|
|
||||||
const signedSwapData = getSignedSwapData(swap);
|
|
||||||
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
||||||
const mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee, 0);
|
const mtx = await createMetaTransactionAsync(getSwapData(swap), _protocolFee, 0);
|
||||||
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
||||||
const receipt = await zeroEx
|
const receipt = await zeroEx
|
||||||
.executeMetaTransaction(mtx, mtx.signature)
|
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
|
||||||
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
||||||
const relayerEthRefund = relayerEthBalanceBefore
|
const relayerEthRefund = relayerEthBalanceBefore
|
||||||
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
||||||
@@ -259,7 +249,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
taker,
|
taker,
|
||||||
callDataHash,
|
|
||||||
sender: zeroEx.address,
|
sender: zeroEx.address,
|
||||||
data: NULL_BYTES,
|
data: NULL_BYTES,
|
||||||
},
|
},
|
||||||
@@ -268,15 +257,13 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can call `transformERC20()` with signed calldata and a relayer fee', async () => {
|
it('can call `transformERC20()` with calldata and a relayer fee', async () => {
|
||||||
const swap = await generateSwapAsync();
|
const swap = await generateSwapAsync();
|
||||||
const callDataHash = hexUtils.hash(getSwapData(swap));
|
|
||||||
const signedSwapData = getSignedSwapData(swap);
|
|
||||||
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
||||||
const mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee);
|
const mtx = await createMetaTransactionAsync(getSwapData(swap), _protocolFee);
|
||||||
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
||||||
const receipt = await zeroEx
|
const receipt = await zeroEx
|
||||||
.executeMetaTransaction(mtx, mtx.signature)
|
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
|
||||||
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
||||||
const relayerEthRefund = relayerEthBalanceBefore
|
const relayerEthRefund = relayerEthBalanceBefore
|
||||||
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
||||||
@@ -295,7 +282,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
taker,
|
taker,
|
||||||
callDataHash,
|
|
||||||
sender: zeroEx.address,
|
sender: zeroEx.address,
|
||||||
data: NULL_BYTES,
|
data: NULL_BYTES,
|
||||||
},
|
},
|
||||||
@@ -304,51 +290,13 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can call `transformERC20()` with wrongly signed calldata and a relayer fee', async () => {
|
it('`transformERC20()` can fill RFQT order', async () => {
|
||||||
const swap = await generateSwapAsync();
|
|
||||||
const signedSwapData = getSignedSwapData(swap, hexUtils.random());
|
|
||||||
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
|
||||||
const mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee);
|
|
||||||
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
|
||||||
const receipt = await zeroEx
|
|
||||||
.executeMetaTransaction(mtx, mtx.signature)
|
|
||||||
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
|
||||||
const relayerEthRefund = relayerEthBalanceBefore
|
|
||||||
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
|
||||||
.minus(GAS_PRICE.times(receipt.gasUsed));
|
|
||||||
// Ensure the relayer got back the unused protocol fees.
|
|
||||||
expect(relayerEthRefund).to.bignumber.eq(protocolFee.times(GAS_PRICE));
|
|
||||||
// Ensure the relayer got paid mtx fees.
|
|
||||||
expect(await feeToken.balanceOf(relayer).callAsync()).to.bignumber.eq(mtx.feeAmount);
|
|
||||||
// Ensure the taker got output tokens.
|
|
||||||
expect(await outputToken.balanceOf(taker).callAsync()).to.bignumber.eq(swap.minOutputTokenAmount);
|
|
||||||
// Ensure the maker got input tokens.
|
|
||||||
expect(await inputToken.balanceOf(maker).callAsync()).to.bignumber.eq(swap.inputTokenAmount);
|
|
||||||
// Check events.
|
|
||||||
verifyEventsFromLogs(
|
|
||||||
receipt.logs,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
taker,
|
|
||||||
// Only signed calldata should have a nonzero hash.
|
|
||||||
callDataHash: NULL_BYTES32,
|
|
||||||
sender: zeroEx.address,
|
|
||||||
data: NULL_BYTES,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'TransformerMetadata',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('`transformERC20()` can fill RFQT order if calldata is signed', async () => {
|
|
||||||
const swap = await generateSwapAsync({}, true);
|
const swap = await generateSwapAsync({}, true);
|
||||||
const callDataHash = hexUtils.hash(getSwapData(swap));
|
|
||||||
const signedSwapData = getSignedSwapData(swap);
|
|
||||||
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
||||||
const mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee, 0);
|
const mtx = await createMetaTransactionAsync(getSwapData(swap), _protocolFee, 0);
|
||||||
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
||||||
const receipt = await zeroEx
|
const receipt = await zeroEx
|
||||||
.executeMetaTransaction(mtx, mtx.signature)
|
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
|
||||||
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
||||||
const relayerEthRefund = relayerEthBalanceBefore
|
const relayerEthRefund = relayerEthBalanceBefore
|
||||||
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
||||||
@@ -367,7 +315,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
taker,
|
taker,
|
||||||
callDataHash,
|
|
||||||
sender: zeroEx.address,
|
sender: zeroEx.address,
|
||||||
data: NULL_BYTES,
|
data: NULL_BYTES,
|
||||||
},
|
},
|
||||||
@@ -376,16 +323,15 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('`transformERC20()` can fill RFQT order if calldata is not signed but no quote signer configured', async () => {
|
it('`transformERC20()` can fill RFQT order if quote signer configured', async () => {
|
||||||
const swap = await generateSwapAsync({}, true);
|
const swap = await generateSwapAsync({}, true);
|
||||||
const callData = getSwapData(swap);
|
const callData = getSwapData(swap);
|
||||||
const callDataHash = hexUtils.hash(callData);
|
|
||||||
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
||||||
const mtx = await createMetaTransactionAsync(callData, _protocolFee, 0);
|
const mtx = await createMetaTransactionAsync(callData, _protocolFee, 0);
|
||||||
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
|
||||||
await zeroEx.setQuoteSigner(NULL_ADDRESS).awaitTransactionSuccessAsync({ from: owner });
|
await zeroEx.setQuoteSigner(NULL_ADDRESS).awaitTransactionSuccessAsync({ from: owner });
|
||||||
const receipt = await zeroEx
|
const receipt = await zeroEx
|
||||||
.executeMetaTransaction(mtx, mtx.signature)
|
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
|
||||||
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
||||||
const relayerEthRefund = relayerEthBalanceBefore
|
const relayerEthRefund = relayerEthBalanceBefore
|
||||||
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
|
||||||
@@ -404,7 +350,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
taker,
|
taker,
|
||||||
callDataHash,
|
|
||||||
sender: zeroEx.address,
|
sender: zeroEx.address,
|
||||||
data: NULL_BYTES,
|
data: NULL_BYTES,
|
||||||
},
|
},
|
||||||
@@ -412,15 +357,4 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
|
|||||||
'TransformerMetadata',
|
'TransformerMetadata',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('`transformERC20()` cannot fill RFQT order if calldata is not signed', async () => {
|
|
||||||
const swap = await generateSwapAsync({}, true);
|
|
||||||
const callData = getSwapData(swap);
|
|
||||||
const _protocolFee = protocolFee.times(GAS_PRICE).times(swap.orders.length + 1); // Pay a little more fee than needed.
|
|
||||||
const mtx = await createMetaTransactionAsync(callData, _protocolFee, 0);
|
|
||||||
const tx = zeroEx
|
|
||||||
.executeMetaTransaction(mtx, mtx.signature)
|
|
||||||
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
|
|
||||||
return expect(tx).to.revertWith(new ZeroExRevertErrors.MetaTransactions.MetaTransactionCallFailedError());
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -10,9 +10,12 @@ export * from '../test/generated-wrappers/test_contract_wrapper';
|
|||||||
export * from '../test/generated-wrappers/test_dydx_user';
|
export * from '../test/generated-wrappers/test_dydx_user';
|
||||||
export * from '../test/generated-wrappers/test_eth2_dai';
|
export * from '../test/generated-wrappers/test_eth2_dai';
|
||||||
export * from '../test/generated-wrappers/test_eth2_dai_bridge';
|
export * from '../test/generated-wrappers/test_eth2_dai_bridge';
|
||||||
|
export * from '../test/generated-wrappers/test_fixin_protocol_fees_integration';
|
||||||
export * from '../test/generated-wrappers/test_framework';
|
export * from '../test/generated-wrappers/test_framework';
|
||||||
export * from '../test/generated-wrappers/test_mainnet_aggregator_fills';
|
export * from '../test/generated-wrappers/test_mainnet_aggregator_fills';
|
||||||
export * from '../test/generated-wrappers/test_signature_validation_wallet';
|
export * from '../test/generated-wrappers/test_signature_validation_wallet';
|
||||||
|
export * from '../test/generated-wrappers/test_staking';
|
||||||
export * from '../test/generated-wrappers/test_uniswap_bridge';
|
export * from '../test/generated-wrappers/test_uniswap_bridge';
|
||||||
export * from '../test/generated-wrappers/test_uniswap_exchange';
|
export * from '../test/generated-wrappers/test_uniswap_exchange';
|
||||||
export * from '../test/generated-wrappers/test_uniswap_exchange_factory';
|
export * from '../test/generated-wrappers/test_uniswap_exchange_factory';
|
||||||
|
export * from '../test/generated-wrappers/test_weth_integration';
|
||||||
|
@@ -0,0 +1,85 @@
|
|||||||
|
import { blockchainTests, constants, expect } from '@0x/contracts-test-utils';
|
||||||
|
import { BigNumber, hexUtils } from '@0x/utils';
|
||||||
|
|
||||||
|
import { artifacts } from '../artifacts';
|
||||||
|
import {
|
||||||
|
TestFixinProtocolFeesIntegrationContract,
|
||||||
|
TestStakingContract,
|
||||||
|
TestWethIntegrationContract,
|
||||||
|
} from '../wrappers';
|
||||||
|
|
||||||
|
blockchainTests.resets('ProtocolFeeIntegration', env => {
|
||||||
|
const FEE_MULTIPLIER = 70e3;
|
||||||
|
let owner: string;
|
||||||
|
let taker: string;
|
||||||
|
let protocolFees: TestFixinProtocolFeesIntegrationContract;
|
||||||
|
let staking: TestStakingContract;
|
||||||
|
let weth: TestWethIntegrationContract;
|
||||||
|
let singleFeeAmount: BigNumber;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
[owner, taker] = await env.getAccountAddressesAsync();
|
||||||
|
weth = await TestWethIntegrationContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.TestWethIntegration,
|
||||||
|
env.provider,
|
||||||
|
env.txDefaults,
|
||||||
|
artifacts,
|
||||||
|
);
|
||||||
|
staking = await TestStakingContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.TestStaking,
|
||||||
|
env.provider,
|
||||||
|
env.txDefaults,
|
||||||
|
artifacts,
|
||||||
|
constants.NULL_ADDRESS, // exchange address, which we don't know yet
|
||||||
|
weth.address,
|
||||||
|
);
|
||||||
|
protocolFees = await TestFixinProtocolFeesIntegrationContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.TestFixinProtocolFeesIntegration,
|
||||||
|
env.provider,
|
||||||
|
{ ...env.txDefaults, from: taker },
|
||||||
|
artifacts,
|
||||||
|
weth.address,
|
||||||
|
staking.address,
|
||||||
|
FEE_MULTIPLIER,
|
||||||
|
);
|
||||||
|
await staking.addAuthorizedAddress(owner).awaitTransactionSuccessAsync();
|
||||||
|
await staking.addExchangeAddress(protocolFees.address).awaitTransactionSuccessAsync({ from: owner });
|
||||||
|
await weth.mint(taker, constants.ONE_ETHER).awaitTransactionSuccessAsync();
|
||||||
|
await weth.approve(protocolFees.address, constants.ONE_ETHER).awaitTransactionSuccessAsync({ from: taker });
|
||||||
|
|
||||||
|
singleFeeAmount = await protocolFees.getSingleProtocolFee().callAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fee collection integration', () => {
|
||||||
|
const pool0 = constants.NULL_BYTES32;
|
||||||
|
const poolId = hexUtils.random();
|
||||||
|
|
||||||
|
it('should collect fees for pool 0', async () => {
|
||||||
|
await protocolFees.collectProtocolFee(pool0).awaitTransactionSuccessAsync({ value: singleFeeAmount });
|
||||||
|
await protocolFees.transferFeesForPool(pool0).awaitTransactionSuccessAsync();
|
||||||
|
|
||||||
|
// Fees in the pool bytes32(0) don't get attributed to a pool.
|
||||||
|
await expect(
|
||||||
|
(await staking.getStakingPoolStatsThisEpoch(pool0).callAsync()).feesCollected,
|
||||||
|
).to.bignumber.equal(constants.ZERO_AMOUNT);
|
||||||
|
|
||||||
|
// Expected amount is singleFeeAmount - 1 because we leave 1 wei of WETH behind for future gas savings.
|
||||||
|
return expect(await weth.balanceOf(staking.address).callAsync()).to.bignumber.equal(
|
||||||
|
singleFeeAmount.minus(1),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should collect fees for non-zero pool', async () => {
|
||||||
|
const eth100 = constants.ONE_ETHER.multipliedBy(100);
|
||||||
|
await staking.createTestPool(poolId, eth100, eth100).awaitTransactionSuccessAsync();
|
||||||
|
|
||||||
|
await protocolFees.collectProtocolFee(poolId).awaitTransactionSuccessAsync({ value: singleFeeAmount });
|
||||||
|
await protocolFees.transferFeesForPool(poolId).awaitTransactionSuccessAsync();
|
||||||
|
|
||||||
|
// Expected amount is singleFeeAmount - 1 because we leave 1 wei of WETH behind for future gas savings.
|
||||||
|
return expect(
|
||||||
|
(await staking.getStakingPoolStatsThisEpoch(poolId).callAsync()).feesCollected,
|
||||||
|
).to.bignumber.equal(singleFeeAmount.minus(1));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -11,11 +11,14 @@
|
|||||||
"test/generated-artifacts/TestDydxUser.json",
|
"test/generated-artifacts/TestDydxUser.json",
|
||||||
"test/generated-artifacts/TestEth2Dai.json",
|
"test/generated-artifacts/TestEth2Dai.json",
|
||||||
"test/generated-artifacts/TestEth2DaiBridge.json",
|
"test/generated-artifacts/TestEth2DaiBridge.json",
|
||||||
|
"test/generated-artifacts/TestFixinProtocolFeesIntegration.json",
|
||||||
"test/generated-artifacts/TestFramework.json",
|
"test/generated-artifacts/TestFramework.json",
|
||||||
"test/generated-artifacts/TestMainnetAggregatorFills.json",
|
"test/generated-artifacts/TestMainnetAggregatorFills.json",
|
||||||
"test/generated-artifacts/TestSignatureValidationWallet.json",
|
"test/generated-artifacts/TestSignatureValidationWallet.json",
|
||||||
|
"test/generated-artifacts/TestStaking.json",
|
||||||
"test/generated-artifacts/TestUniswapBridge.json",
|
"test/generated-artifacts/TestUniswapBridge.json",
|
||||||
"test/generated-artifacts/TestUniswapExchange.json",
|
"test/generated-artifacts/TestUniswapExchange.json",
|
||||||
"test/generated-artifacts/TestUniswapExchangeFactory.json"
|
"test/generated-artifacts/TestUniswapExchangeFactory.json",
|
||||||
|
"test/generated-artifacts/TestWethIntegration.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "4.1.19",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "4.1.18",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "4.1.17",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "4.1.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "4.1.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "4.1.14",
|
"version": "4.1.14",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v4.1.19 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.1.18 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.1.17 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.1.16 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.1.15 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v4.1.14 - _November 13, 2020_
|
## v4.1.14 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-multisig",
|
"name": "@0x/contracts-multisig",
|
||||||
"version": "4.1.14",
|
"version": "4.1.19",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -49,18 +49,18 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
@@ -78,9 +78,9 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"ethereum-types": "^3.3.3"
|
"ethereum-types": "^3.4.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -1,4 +1,49 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1608105788,
|
||||||
|
"version": "2.0.26",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "2.0.25",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "2.0.24",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "2.0.23",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "2.0.22",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "2.0.21",
|
"version": "2.0.21",
|
||||||
|
@@ -5,6 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v2.0.26 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.0.25 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.0.24 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.0.23 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v2.0.22 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v2.0.21 - _November 13, 2020_
|
## v2.0.21 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"artifactsDir": "./test/generated-artifacts",
|
"artifactsDir": "./test/generated-artifacts",
|
||||||
"contractsDir": "./contracts",
|
"contractsDir": "./contracts",
|
||||||
"useDockerisedSolc": false,
|
"useDockerisedSolc": false,
|
||||||
"isOfflineMode": true,
|
"isOfflineMode": false,
|
||||||
"shouldSaveStandardInput": true,
|
"shouldSaveStandardInput": true,
|
||||||
"compilerSettings": {
|
"compilerSettings": {
|
||||||
"evmVersion": "istanbul",
|
"evmVersion": "istanbul",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-staking",
|
"name": "@0x/contracts-staking",
|
||||||
"version": "2.0.21",
|
"version": "2.0.26",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -53,20 +53,20 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-asset-proxy": "^3.6.5",
|
"@0x/contracts-asset-proxy": "^3.7.0",
|
||||||
"@0x/contracts-dev-utils": "^1.3.12",
|
"@0x/contracts-dev-utils": "^1.3.17",
|
||||||
"@0x/contracts-erc20": "^3.2.8",
|
"@0x/contracts-erc20": "^3.2.12",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.14",
|
"@0x/contracts-exchange-libs": "^4.3.18",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-utils": "^4.5.8",
|
"@0x/contracts-utils": "^4.6.3",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/node": "12.12.54",
|
"@types/node": "12.12.54",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
@@ -87,11 +87,11 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"ethereumjs-util": "^5.1.1"
|
"ethereumjs-util": "^5.1.1"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
@@ -1,4 +1,40 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "5.3.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "5.3.14",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "5.3.13",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1605763885,
|
||||||
|
"version": "5.3.12",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "5.3.11",
|
"version": "5.3.11",
|
||||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v5.3.15 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v5.3.14 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v5.3.13 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v5.3.12 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v5.3.11 - _November 13, 2020_
|
## v5.3.11 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-test-utils",
|
"name": "@0x/contracts-test-utils",
|
||||||
"version": "5.3.11",
|
"version": "5.3.15",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
@@ -42,20 +42,20 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.17",
|
"@0x/assert": "^3.0.19",
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/contract-addresses": "^5.3.0",
|
"@0x/contract-addresses": "^5.6.0",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/json-schemas": "^5.3.3",
|
"@0x/json-schemas": "^5.3.4",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-coverage": "^4.0.18",
|
"@0x/sol-coverage": "^4.0.24",
|
||||||
"@0x/sol-profiler": "^4.1.8",
|
"@0x/sol-profiler": "^4.1.14",
|
||||||
"@0x/sol-trace": "^3.0.18",
|
"@0x/sol-trace": "^3.0.24",
|
||||||
"@0x/subproviders": "^6.1.9",
|
"@0x/subproviders": "^6.2.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/bn.js": "^4.11.0",
|
"@types/bn.js": "^4.11.0",
|
||||||
"@types/js-combinatorics": "^0.5.29",
|
"@types/js-combinatorics": "^0.5.29",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
"chai-bignumber": "^3.0.0",
|
"chai-bignumber": "^3.0.0",
|
||||||
"decimal.js": "^10.2.0",
|
"decimal.js": "^10.2.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"ethereum-types": "^3.3.3",
|
"ethereum-types": "^3.4.0",
|
||||||
"ethereumjs-util": "^5.1.1",
|
"ethereumjs-util": "^5.1.1",
|
||||||
"ethers": "~4.0.4",
|
"ethers": "~4.0.4",
|
||||||
"js-combinatorics": "^0.5.3",
|
"js-combinatorics": "^0.5.3",
|
||||||
|
@@ -1,4 +1,41 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1607485227,
|
||||||
|
"version": "4.6.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "4.6.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1606961263,
|
||||||
|
"version": "4.6.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "4.6.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `uint128` functions to `LibSafeMathV06`",
|
||||||
|
"pr": 27
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1605763885
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1605302002,
|
"timestamp": 1605302002,
|
||||||
"version": "4.5.8",
|
"version": "4.5.8",
|
||||||
|
@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v4.6.3 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.6.2 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.6.1 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.6.0 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Add `uint128` functions to `LibSafeMathV06` (#27)
|
||||||
|
|
||||||
## v4.5.8 - _November 13, 2020_
|
## v4.5.8 - _November 13, 2020_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -105,4 +105,86 @@ library LibSafeMathV06 {
|
|||||||
{
|
{
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function safeMul128(uint128 a, uint128 b)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint128)
|
||||||
|
{
|
||||||
|
if (a == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint128 c = a * b;
|
||||||
|
if (c / a != b) {
|
||||||
|
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
|
||||||
|
LibSafeMathRichErrorsV06.BinOpErrorCodes.MULTIPLICATION_OVERFLOW,
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeDiv128(uint128 a, uint128 b)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint128)
|
||||||
|
{
|
||||||
|
if (b == 0) {
|
||||||
|
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
|
||||||
|
LibSafeMathRichErrorsV06.BinOpErrorCodes.DIVISION_BY_ZERO,
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
));
|
||||||
|
}
|
||||||
|
uint128 c = a / b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeSub128(uint128 a, uint128 b)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint128)
|
||||||
|
{
|
||||||
|
if (b > a) {
|
||||||
|
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
|
||||||
|
LibSafeMathRichErrorsV06.BinOpErrorCodes.SUBTRACTION_UNDERFLOW,
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeAdd128(uint128 a, uint128 b)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint128)
|
||||||
|
{
|
||||||
|
uint128 c = a + b;
|
||||||
|
if (c < a) {
|
||||||
|
LibRichErrorsV06.rrevert(LibSafeMathRichErrorsV06.Uint256BinOpError(
|
||||||
|
LibSafeMathRichErrorsV06.BinOpErrorCodes.ADDITION_OVERFLOW,
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function max128(uint128 a, uint128 b)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint128)
|
||||||
|
{
|
||||||
|
return a >= b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function min128(uint128 a, uint128 b)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (uint128)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-utils",
|
"name": "@0x/contracts-utils",
|
||||||
"version": "4.5.8",
|
"version": "4.6.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -50,15 +50,15 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.4.7",
|
"@0x/abi-gen": "^5.4.13",
|
||||||
"@0x/contracts-gen": "2.0.18",
|
"@0x/contracts-gen": "^2.0.24",
|
||||||
"@0x/contracts-test-utils": "^5.3.11",
|
"@0x/contracts-test-utils": "^5.3.15",
|
||||||
"@0x/dev-utils": "^4.0.1",
|
"@0x/dev-utils": "^4.1.3",
|
||||||
"@0x/order-utils": "^10.4.6",
|
"@0x/order-utils": "^10.4.10",
|
||||||
"@0x/sol-compiler": "^4.2.7",
|
"@0x/sol-compiler": "^4.4.1",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/types": "^3.3.0",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/web3-wrapper": "^7.2.8",
|
"@0x/web3-wrapper": "^7.3.0",
|
||||||
"@types/bn.js": "^4.11.0",
|
"@types/bn.js": "^4.11.0",
|
||||||
"@types/lodash": "4.14.104",
|
"@types/lodash": "4.14.104",
|
||||||
"@types/mocha": "^5.2.7",
|
"@types/mocha": "^5.2.7",
|
||||||
@@ -79,11 +79,11 @@
|
|||||||
"typescript": "3.0.1"
|
"typescript": "3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.11",
|
"@0x/base-contract": "^6.2.14",
|
||||||
"@0x/typescript-typings": "^5.1.5",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
"@0x/utils": "^6.1.0",
|
"@0x/utils": "^6.1.1",
|
||||||
"bn.js": "^4.11.8",
|
"bn.js": "^4.11.8",
|
||||||
"ethereum-types": "^3.3.3"
|
"ethereum-types": "^3.4.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
@@ -8,3 +8,4 @@
|
|||||||
# Blacklist tests in lib
|
# Blacklist tests in lib
|
||||||
/lib/test/*
|
/lib/test/*
|
||||||
# Package specific ignore
|
# Package specific ignore
|
||||||
|
/lib/scripts/*
|
||||||
|
@@ -1,4 +1,129 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "0.13.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Address audit feedback in UniswapFeature",
|
||||||
|
"pr": 82
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Always transfer `msg.value` to the liquidity provider contract in LiquidityProviderFeature to",
|
||||||
|
"pr": 82
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Remove backwards compatibility with old PLP/bridge interface in `LiquidityProviderFeature` and `MixinZeroExBridge`",
|
||||||
|
"pr": 85
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1608105788
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.12.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add test for selector collisions on the proxy",
|
||||||
|
"pr": 74
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Move tooling out into `@0x/protocol-utils`.",
|
||||||
|
"pr": 76
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1607485227
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1607381756,
|
||||||
|
"version": "0.11.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.11.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Turn `LibTokenSpender` into `FixinTokenSpender`",
|
||||||
|
"pr": 38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Use bloom filters to check if a token is greedy and do not optimistically fall through transferFrom() if so",
|
||||||
|
"pr": 38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Revert to original proxy implementation",
|
||||||
|
"pr": 38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Fix incorrect cancel order event param",
|
||||||
|
"pr": 38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add a gas limit to first `LibTokenSpender` and `UniswapFeature` transfer",
|
||||||
|
"pr": 38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Convert metatransactions to use `LibSignature`",
|
||||||
|
"pr": 31
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add metatransaction support for limit orders",
|
||||||
|
"pr": 44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Require RFQ orders to specify a transaction origin, and allow approved alternative addresses",
|
||||||
|
"pr": 47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Do not try to pull all tokens if selling all ETH in `TransformERC20Feature`",
|
||||||
|
"pr": 46
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Remove protocol fees from all RFQ orders and add `taker` field to RFQ orders",
|
||||||
|
"pr": 45
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Fix getRfqOrderInfo() to return status INVALID when missing txOrigin",
|
||||||
|
"pr": 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Remove calldata signing functionality",
|
||||||
|
"pr": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add a permissionless transformer deployer",
|
||||||
|
"pr": 55
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add Crypto.com to `BridgeAdapter`",
|
||||||
|
"pr": 43
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Use `FeeCollectorController` contract for deploying `FeeCollector`s",
|
||||||
|
"pr": 59
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1606961263
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.10.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `checkAllowance` flag to LibTokenSpender.spendERC20Tokens",
|
||||||
|
"pr": 39
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Use new `checkAllowance` flag in LiquidityProviderFeature, TransformERC20Feature, and MetaTransactionsFeature",
|
||||||
|
"pr": 39
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add native orders features",
|
||||||
|
"pr": 27
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1605763885
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "0.9.0",
|
"version": "0.9.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
@@ -55,6 +180,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Add `LibSignature` library",
|
"note": "Add `LibSignature` library",
|
||||||
"pr": 21
|
"pr": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add `LimitOrdersFeature`",
|
||||||
|
"pr": 27
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"timestamp": 1604355662
|
"timestamp": 1604355662
|
||||||
|
@@ -5,6 +5,45 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v0.13.0 - _December 16, 2020_
|
||||||
|
|
||||||
|
* Address audit feedback in UniswapFeature (#82)
|
||||||
|
* Always transfer `msg.value` to the liquidity provider contract in LiquidityProviderFeature to (#82)
|
||||||
|
* Remove backwards compatibility with old PLP/bridge interface in `LiquidityProviderFeature` and `MixinZeroExBridge` (#85)
|
||||||
|
|
||||||
|
## v0.12.0 - _December 9, 2020_
|
||||||
|
|
||||||
|
* Add test for selector collisions on the proxy (#74)
|
||||||
|
* Move tooling out into `@0x/protocol-utils`. (#76)
|
||||||
|
|
||||||
|
## v0.11.1 - _December 7, 2020_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v0.11.0 - _December 3, 2020_
|
||||||
|
|
||||||
|
* Turn `LibTokenSpender` into `FixinTokenSpender` (#38)
|
||||||
|
* Use bloom filters to check if a token is greedy and do not optimistically fall through transferFrom() if so (#38)
|
||||||
|
* Revert to original proxy implementation (#38)
|
||||||
|
* Fix incorrect cancel order event param (#38)
|
||||||
|
* Add a gas limit to first `LibTokenSpender` and `UniswapFeature` transfer (#38)
|
||||||
|
* Convert metatransactions to use `LibSignature` (#31)
|
||||||
|
* Add metatransaction support for limit orders (#44)
|
||||||
|
* Require RFQ orders to specify a transaction origin, and allow approved alternative addresses (#47)
|
||||||
|
* Do not try to pull all tokens if selling all ETH in `TransformERC20Feature` (#46)
|
||||||
|
* Remove protocol fees from all RFQ orders and add `taker` field to RFQ orders (#45)
|
||||||
|
* Fix getRfqOrderInfo() to return status INVALID when missing txOrigin (#50)
|
||||||
|
* Remove calldata signing functionality (#51)
|
||||||
|
* Add a permissionless transformer deployer (#55)
|
||||||
|
* Add Crypto.com to `BridgeAdapter` (#43)
|
||||||
|
* Use `FeeCollectorController` contract for deploying `FeeCollector`s (#59)
|
||||||
|
|
||||||
|
## v0.10.0 - _November 19, 2020_
|
||||||
|
|
||||||
|
* Add `checkAllowance` flag to LibTokenSpender.spendERC20Tokens (#39)
|
||||||
|
* Use new `checkAllowance` flag in LiquidityProviderFeature, TransformERC20Feature, and MetaTransactionsFeature (#39)
|
||||||
|
* Add native orders features (#27)
|
||||||
|
|
||||||
## v0.9.0 - _November 13, 2020_
|
## v0.9.0 - _November 13, 2020_
|
||||||
|
|
||||||
* Rewrite the ZeroEx contract in Yul (#23)
|
* Rewrite the ZeroEx contract in Yul (#23)
|
||||||
@@ -25,6 +64,7 @@ CHANGELOG
|
|||||||
|
|
||||||
* Add support for collecting protocol fees in ETH or WETH (#2)
|
* Add support for collecting protocol fees in ETH or WETH (#2)
|
||||||
* Add `LibSignature` library (#21)
|
* Add `LibSignature` library (#21)
|
||||||
|
* Add `LimitOrdersFeature` (#27)
|
||||||
|
|
||||||
## v0.5.1 - _October 28, 2020_
|
## v0.5.1 - _October 28, 2020_
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
"useDockerisedSolc": false,
|
"useDockerisedSolc": false,
|
||||||
"isOfflineMode": false,
|
"isOfflineMode": false,
|
||||||
"shouldSaveStandardInput": true,
|
"shouldSaveStandardInput": true,
|
||||||
|
"shouldCompileIndependently": true,
|
||||||
"compilerSettings": {
|
"compilerSettings": {
|
||||||
"evmVersion": "istanbul",
|
"evmVersion": "istanbul",
|
||||||
"optimizer": {
|
"optimizer": {
|
||||||
@@ -19,7 +20,8 @@
|
|||||||
"evm.bytecode.object",
|
"evm.bytecode.object",
|
||||||
"evm.bytecode.sourceMap",
|
"evm.bytecode.sourceMap",
|
||||||
"evm.deployedBytecode.object",
|
"evm.deployedBytecode.object",
|
||||||
"evm.deployedBytecode.sourceMap"
|
"evm.deployedBytecode.sourceMap",
|
||||||
|
"evm.methodIdentifiers"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@ import "./features/ITransformERC20Feature.sol";
|
|||||||
import "./features/IMetaTransactionsFeature.sol";
|
import "./features/IMetaTransactionsFeature.sol";
|
||||||
import "./features/IUniswapFeature.sol";
|
import "./features/IUniswapFeature.sol";
|
||||||
import "./features/ILiquidityProviderFeature.sol";
|
import "./features/ILiquidityProviderFeature.sol";
|
||||||
|
import "./features/INativeOrdersFeature.sol";
|
||||||
|
|
||||||
|
|
||||||
/// @dev Interface for a fully featured Exchange Proxy.
|
/// @dev Interface for a fully featured Exchange Proxy.
|
||||||
@@ -38,7 +39,8 @@ interface IZeroEx is
|
|||||||
ITransformERC20Feature,
|
ITransformERC20Feature,
|
||||||
IMetaTransactionsFeature,
|
IMetaTransactionsFeature,
|
||||||
IUniswapFeature,
|
IUniswapFeature,
|
||||||
ILiquidityProviderFeature
|
ILiquidityProviderFeature,
|
||||||
|
INativeOrdersFeature
|
||||||
{
|
{
|
||||||
// solhint-disable state-visibility
|
// solhint-disable state-visibility
|
||||||
|
|
||||||
|
@@ -19,12 +19,19 @@
|
|||||||
pragma solidity ^0.6.5;
|
pragma solidity ^0.6.5;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||||
|
import "./migrations/LibBootstrap.sol";
|
||||||
import "./features/BootstrapFeature.sol";
|
import "./features/BootstrapFeature.sol";
|
||||||
import "./storage/LibProxyStorage.sol";
|
import "./storage/LibProxyStorage.sol";
|
||||||
|
import "./errors/LibProxyRichErrors.sol";
|
||||||
|
|
||||||
|
|
||||||
/// @dev An extensible proxy contract that serves as a universal entry point for
|
/// @dev An extensible proxy contract that serves as a universal entry point for
|
||||||
/// interacting with the 0x protocol.
|
/// interacting with the 0x protocol.
|
||||||
contract ZeroEx {
|
contract ZeroEx {
|
||||||
|
// solhint-disable separate-by-one-line-in-contract,indent,var-name-mixedcase
|
||||||
|
using LibBytesV06 for bytes;
|
||||||
|
|
||||||
/// @dev Construct this contract and register the `BootstrapFeature` feature.
|
/// @dev Construct this contract and register the `BootstrapFeature` feature.
|
||||||
/// After constructing this contract, `bootstrap()` should be called
|
/// After constructing this contract, `bootstrap()` should be called
|
||||||
/// by `bootstrap()` to seed the initial feature set.
|
/// by `bootstrap()` to seed the initial feature set.
|
||||||
@@ -37,55 +44,48 @@ contract ZeroEx {
|
|||||||
address(bootstrap);
|
address(bootstrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// solhint-disable state-visibility
|
// solhint-disable state-visibility
|
||||||
|
|
||||||
/// @dev Forwards calls to the appropriate implementation contract.
|
/// @dev Forwards calls to the appropriate implementation contract.
|
||||||
fallback() external payable {
|
fallback() external payable {
|
||||||
// This is used in assembly below as impls_slot.
|
bytes4 selector = msg.data.readBytes4(0);
|
||||||
mapping(bytes4 => address) storage impls =
|
address impl = getFunctionImplementation(selector);
|
||||||
LibProxyStorage.getStorage().impls;
|
if (impl == address(0)) {
|
||||||
|
_revertWithData(LibProxyRichErrors.NotImplementedError(selector));
|
||||||
assembly {
|
|
||||||
let cdlen := calldatasize()
|
|
||||||
|
|
||||||
// equivalent of receive() external payable {}
|
|
||||||
if iszero(cdlen) {
|
|
||||||
return(0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store at 0x40, to leave 0x00-0x3F for slot calculation below.
|
|
||||||
calldatacopy(0x40, 0, cdlen)
|
|
||||||
let selector := and(mload(0x40), 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
|
|
||||||
|
|
||||||
// Slot for impls[selector] is keccak256(selector . impls_slot).
|
|
||||||
mstore(0, selector)
|
|
||||||
mstore(0x20, impls_slot)
|
|
||||||
let slot := keccak256(0, 0x40)
|
|
||||||
|
|
||||||
let delegate := sload(slot)
|
|
||||||
if iszero(delegate) {
|
|
||||||
// Revert with:
|
|
||||||
// abi.encodeWithSelector(
|
|
||||||
// bytes4(keccak256("NotImplementedError(bytes4)")),
|
|
||||||
// selector)
|
|
||||||
mstore(0, 0x734e6e1c00000000000000000000000000000000000000000000000000000000)
|
|
||||||
mstore(4, selector)
|
|
||||||
revert(0, 0x24)
|
|
||||||
}
|
|
||||||
|
|
||||||
let success := delegatecall(
|
|
||||||
gas(),
|
|
||||||
delegate,
|
|
||||||
0x40, cdlen,
|
|
||||||
0, 0
|
|
||||||
)
|
|
||||||
let rdlen := returndatasize()
|
|
||||||
returndatacopy(0, 0, rdlen)
|
|
||||||
if success {
|
|
||||||
return(0, rdlen)
|
|
||||||
}
|
|
||||||
revert(0, rdlen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(bool success, bytes memory resultData) = impl.delegatecall(msg.data);
|
||||||
|
if (!success) {
|
||||||
|
_revertWithData(resultData);
|
||||||
|
}
|
||||||
|
_returnWithData(resultData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Fallback for just receiving ether.
|
||||||
|
receive() external payable {}
|
||||||
|
|
||||||
|
// solhint-enable state-visibility
|
||||||
|
|
||||||
|
/// @dev Get the implementation contract of a registered function.
|
||||||
|
/// @param selector The function selector.
|
||||||
|
/// @return impl The implementation contract address.
|
||||||
|
function getFunctionImplementation(bytes4 selector)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (address impl)
|
||||||
|
{
|
||||||
|
return LibProxyStorage.getStorage().impls[selector];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Revert with arbitrary bytes.
|
||||||
|
/// @param data Revert data.
|
||||||
|
function _revertWithData(bytes memory data) private pure {
|
||||||
|
assembly { revert(add(data, 32), mload(data)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Return with arbitrary bytes.
|
||||||
|
/// @param data Return data.
|
||||||
|
function _returnWithData(bytes memory data) private pure {
|
||||||
|
assembly { return(add(data, 32), mload(data)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
91
contracts/zero-ex/contracts/src/ZeroExOptimized.sol
Normal file
91
contracts/zero-ex/contracts/src/ZeroExOptimized.sol
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "./features/BootstrapFeature.sol";
|
||||||
|
import "./storage/LibProxyStorage.sol";
|
||||||
|
|
||||||
|
/// @dev An extensible proxy contract that serves as a universal entry point for
|
||||||
|
/// interacting with the 0x protocol. Optimized version of ZeroEx.
|
||||||
|
contract ZeroExOptimized {
|
||||||
|
/// @dev Construct this contract and register the `BootstrapFeature` feature.
|
||||||
|
/// After constructing this contract, `bootstrap()` should be called
|
||||||
|
/// by `bootstrap()` to seed the initial feature set.
|
||||||
|
/// @param bootstrapper Who can call `bootstrap()`.
|
||||||
|
constructor(address bootstrapper) public {
|
||||||
|
// Temporarily create and register the bootstrap feature.
|
||||||
|
// It will deregister itself after `bootstrap()` has been called.
|
||||||
|
BootstrapFeature bootstrap = new BootstrapFeature(bootstrapper);
|
||||||
|
LibProxyStorage.getStorage().impls[bootstrap.bootstrap.selector] =
|
||||||
|
address(bootstrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// solhint-disable state-visibility
|
||||||
|
|
||||||
|
/// @dev Forwards calls to the appropriate implementation contract.
|
||||||
|
fallback() external payable {
|
||||||
|
// This is used in assembly below as impls_slot.
|
||||||
|
mapping(bytes4 => address) storage impls =
|
||||||
|
LibProxyStorage.getStorage().impls;
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
let cdlen := calldatasize()
|
||||||
|
|
||||||
|
// equivalent of receive() external payable {}
|
||||||
|
if iszero(cdlen) {
|
||||||
|
return(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store at 0x40, to leave 0x00-0x3F for slot calculation below.
|
||||||
|
calldatacopy(0x40, 0, cdlen)
|
||||||
|
let selector := and(mload(0x40), 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
|
||||||
|
|
||||||
|
// Slot for impls[selector] is keccak256(selector . impls_slot).
|
||||||
|
mstore(0, selector)
|
||||||
|
mstore(0x20, impls_slot)
|
||||||
|
let slot := keccak256(0, 0x40)
|
||||||
|
|
||||||
|
let delegate := sload(slot)
|
||||||
|
if iszero(delegate) {
|
||||||
|
// Revert with:
|
||||||
|
// abi.encodeWithSelector(
|
||||||
|
// bytes4(keccak256("NotImplementedError(bytes4)")),
|
||||||
|
// selector)
|
||||||
|
mstore(0, 0x734e6e1c00000000000000000000000000000000000000000000000000000000)
|
||||||
|
mstore(4, selector)
|
||||||
|
revert(0, 0x24)
|
||||||
|
}
|
||||||
|
|
||||||
|
let success := delegatecall(
|
||||||
|
gas(),
|
||||||
|
delegate,
|
||||||
|
0x40, cdlen,
|
||||||
|
0, 0
|
||||||
|
)
|
||||||
|
let rdlen := returndatasize()
|
||||||
|
returndatacopy(0, 0, rdlen)
|
||||||
|
if success {
|
||||||
|
return(0, rdlen)
|
||||||
|
}
|
||||||
|
revert(0, rdlen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
|
||||||
|
|
||||||
|
library LibNativeOrdersRichErrors {
|
||||||
|
|
||||||
|
// solhint-disable func-name-mixedcase
|
||||||
|
|
||||||
|
function ProtocolFeeRefundFailed(
|
||||||
|
address receiver,
|
||||||
|
uint256 refundAmount
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("ProtocolFeeRefundFailed(address,uint256)")),
|
||||||
|
receiver,
|
||||||
|
refundAmount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OrderNotFillableByOriginError(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address txOrigin,
|
||||||
|
address orderTxOrigin
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("OrderNotFillableByOriginError(bytes32,address,address)")),
|
||||||
|
orderHash,
|
||||||
|
txOrigin,
|
||||||
|
orderTxOrigin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OrderNotFillableError(
|
||||||
|
bytes32 orderHash,
|
||||||
|
uint8 orderStatus
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("OrderNotFillableError(bytes32,uint8)")),
|
||||||
|
orderHash,
|
||||||
|
orderStatus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OrderNotSignedByMakerError(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address signer,
|
||||||
|
address maker
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("OrderNotSignedByMakerError(bytes32,address,address)")),
|
||||||
|
orderHash,
|
||||||
|
signer,
|
||||||
|
maker
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OrderNotFillableBySenderError(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address sender,
|
||||||
|
address orderSender
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("OrderNotFillableBySenderError(bytes32,address,address)")),
|
||||||
|
orderHash,
|
||||||
|
sender,
|
||||||
|
orderSender
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OrderNotFillableByTakerError(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address taker,
|
||||||
|
address orderTaker
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("OrderNotFillableByTakerError(bytes32,address,address)")),
|
||||||
|
orderHash,
|
||||||
|
taker,
|
||||||
|
orderTaker
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CancelSaltTooLowError(
|
||||||
|
uint256 minValidSalt,
|
||||||
|
uint256 oldMinValidSalt
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("CancelSaltTooLowError(uint256,uint256)")),
|
||||||
|
minValidSalt,
|
||||||
|
oldMinValidSalt
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function FillOrKillFailedError(
|
||||||
|
bytes32 orderHash,
|
||||||
|
uint256 takerTokenFilledAmount,
|
||||||
|
uint256 takerTokenFillAmount
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("FillOrKillFailedError(bytes32,uint256,uint256)")),
|
||||||
|
orderHash,
|
||||||
|
takerTokenFilledAmount,
|
||||||
|
takerTokenFillAmount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function OnlyOrderMakerAllowed(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address sender,
|
||||||
|
address maker
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes memory)
|
||||||
|
{
|
||||||
|
return abi.encodeWithSelector(
|
||||||
|
bytes4(keccak256("OnlyOrderMakerAllowed(bytes32,address,address)")),
|
||||||
|
orderHash,
|
||||||
|
sender,
|
||||||
|
maker
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -57,9 +57,8 @@ contract FeeCollector is AuthorizableV06 {
|
|||||||
external
|
external
|
||||||
onlyAuthorized
|
onlyAuthorized
|
||||||
{
|
{
|
||||||
// Leave 1 wei behind to avoid expensive zero-->non-zero state change.
|
if (address(this).balance > 0) {
|
||||||
if (address(this).balance > 1) {
|
weth.deposit{value: address(this).balance}();
|
||||||
weth.deposit{value: address(this).balance - 1}();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
92
contracts/zero-ex/contracts/src/external/FeeCollectorController.sol
vendored
Normal file
92
contracts/zero-ex/contracts/src/external/FeeCollectorController.sol
vendored
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||||
|
import "../vendor/v3/IStaking.sol";
|
||||||
|
import "./FeeCollector.sol";
|
||||||
|
import "./LibFeeCollector.sol";
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev A contract that manages `FeeCollector` contracts.
|
||||||
|
contract FeeCollectorController {
|
||||||
|
|
||||||
|
/// @dev Hash of the fee collector init code.
|
||||||
|
bytes32 public immutable FEE_COLLECTOR_INIT_CODE_HASH;
|
||||||
|
/// @dev The WETH contract.
|
||||||
|
IEtherTokenV06 private immutable WETH;
|
||||||
|
/// @dev The staking contract.
|
||||||
|
IStaking private immutable STAKING;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
IEtherTokenV06 weth,
|
||||||
|
IStaking staking
|
||||||
|
)
|
||||||
|
public
|
||||||
|
{
|
||||||
|
FEE_COLLECTOR_INIT_CODE_HASH = keccak256(type(FeeCollector).creationCode);
|
||||||
|
WETH = weth;
|
||||||
|
STAKING = staking;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Deploy (if needed) a `FeeCollector` contract for `poolId`
|
||||||
|
/// and wrap its ETH into WETH. Anyone may call this.
|
||||||
|
/// @param poolId The pool ID associated with the staking pool.
|
||||||
|
/// @return feeCollector The `FeeCollector` contract instance.
|
||||||
|
function prepareFeeCollectorToPayFees(bytes32 poolId)
|
||||||
|
external
|
||||||
|
returns (FeeCollector feeCollector)
|
||||||
|
{
|
||||||
|
feeCollector = getFeeCollector(poolId);
|
||||||
|
uint256 codeSize;
|
||||||
|
assembly {
|
||||||
|
codeSize := extcodesize(feeCollector)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codeSize == 0) {
|
||||||
|
// Create and initialize the contract if necessary.
|
||||||
|
new FeeCollector{salt: bytes32(poolId)}();
|
||||||
|
feeCollector.initialize(WETH, STAKING, poolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address(feeCollector).balance > 1) {
|
||||||
|
feeCollector.convertToWeth(WETH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return feeCollector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Get the `FeeCollector` contract for a given pool ID. The contract
|
||||||
|
/// will not actually exist until `prepareFeeCollectorToPayFees()`
|
||||||
|
/// has been called once.
|
||||||
|
/// @param poolId The pool ID associated with the staking pool.
|
||||||
|
/// @return feeCollector The `FeeCollector` contract instance.
|
||||||
|
function getFeeCollector(bytes32 poolId)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (FeeCollector feeCollector)
|
||||||
|
{
|
||||||
|
return FeeCollector(LibFeeCollector.getFeeCollectorAddress(
|
||||||
|
address(this),
|
||||||
|
FEE_COLLECTOR_INIT_CODE_HASH,
|
||||||
|
poolId
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
43
contracts/zero-ex/contracts/src/external/LibFeeCollector.sol
vendored
Normal file
43
contracts/zero-ex/contracts/src/external/LibFeeCollector.sol
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev Helpers for computing `FeeCollector` contract addresses.
|
||||||
|
library LibFeeCollector {
|
||||||
|
|
||||||
|
/// @dev Compute the CREATE2 address for a fee collector.
|
||||||
|
/// @param controller The address of the `FeeCollectorController` contract.
|
||||||
|
/// @param initCodeHash The init code hash of the `FeeCollector` contract.
|
||||||
|
/// @param poolId The fee collector's pool ID.
|
||||||
|
function getFeeCollectorAddress(address controller, bytes32 initCodeHash, bytes32 poolId)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (address payable feeCollectorAddress)
|
||||||
|
{
|
||||||
|
// Compute the CREATE2 address for the fee collector.
|
||||||
|
return address(uint256(keccak256(abi.encodePacked(
|
||||||
|
byte(0xff),
|
||||||
|
controller,
|
||||||
|
poolId, // pool ID is salt
|
||||||
|
initCodeHash
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
}
|
@@ -68,21 +68,13 @@ contract LiquidityProviderSandbox is
|
|||||||
onlyOwner
|
onlyOwner
|
||||||
override
|
override
|
||||||
{
|
{
|
||||||
try ILiquidityProvider(provider).sellTokenForToken(
|
ILiquidityProvider(provider).sellTokenForToken(
|
||||||
inputToken,
|
inputToken,
|
||||||
outputToken,
|
outputToken,
|
||||||
recipient,
|
recipient,
|
||||||
minBuyAmount,
|
minBuyAmount,
|
||||||
auxiliaryData
|
auxiliaryData
|
||||||
) {} catch {
|
);
|
||||||
IERC20Bridge(provider).bridgeTransferFrom(
|
|
||||||
outputToken,
|
|
||||||
provider,
|
|
||||||
recipient,
|
|
||||||
minBuyAmount,
|
|
||||||
auxiliaryData
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Calls `sellEthForToken` on the given `provider` contract to
|
/// @dev Calls `sellEthForToken` on the given `provider` contract to
|
||||||
|
114
contracts/zero-ex/contracts/src/external/PermissionlessTransformerDeployer.sol
vendored
Normal file
114
contracts/zero-ex/contracts/src/external/PermissionlessTransformerDeployer.sol
vendored
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev Deployer contract for ERC20 transformers.
|
||||||
|
contract PermissionlessTransformerDeployer {
|
||||||
|
/// @dev Emitted when a contract is deployed via `deploy()`.
|
||||||
|
/// @param deployedAddress The address of the deployed contract.
|
||||||
|
/// @param salt The deployment salt.
|
||||||
|
/// @param sender The caller of `deploy()`.
|
||||||
|
event Deployed(address deployedAddress, bytes32 salt, address sender);
|
||||||
|
|
||||||
|
// @dev Mapping of deployed contract address to the deployment salt.
|
||||||
|
mapping (address => bytes32) public toDeploymentSalt;
|
||||||
|
// @dev Mapping of deployed contract address to the init code hash.
|
||||||
|
mapping (address => bytes32) public toInitCodeHash;
|
||||||
|
|
||||||
|
/// @dev Deploy a new contract. Any attached ETH will be forwarded.
|
||||||
|
function deploy(bytes memory bytecode, bytes32 salt)
|
||||||
|
public
|
||||||
|
payable
|
||||||
|
returns (address deployedAddress)
|
||||||
|
{
|
||||||
|
assembly {
|
||||||
|
deployedAddress := create2(callvalue(), add(bytecode, 32), mload(bytecode), salt)
|
||||||
|
}
|
||||||
|
require(deployedAddress != address(0), 'PermissionlessTransformerDeployer/DEPLOY_FAILED');
|
||||||
|
require(isDelegateCallSafe(deployedAddress), 'PermissionlessTransformerDeployer/UNSAFE_CODE');
|
||||||
|
toDeploymentSalt[deployedAddress] = salt;
|
||||||
|
toInitCodeHash[deployedAddress] = keccak256(bytecode);
|
||||||
|
emit Deployed(deployedAddress, salt, msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Checks whether a given address is safe to be called via
|
||||||
|
/// delegatecall. A contract is considered unsafe if it includes any
|
||||||
|
/// of the following opcodes: CALLCODE, DELEGATECALL, SELFDESTRUCT,
|
||||||
|
/// CREATE, CREATE2, SLOAD, and STORE. This code is adapted from
|
||||||
|
/// https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/helpers/IndestructibleRegistry.sol
|
||||||
|
/// @param target The address to check.
|
||||||
|
/// @return True if the contract is considered safe for delegatecall.
|
||||||
|
function isDelegateCallSafe(address target) public view returns (bool) {
|
||||||
|
uint256 size;
|
||||||
|
assembly { size := extcodesize(target) }
|
||||||
|
require(size > 0, 'PermissionlessTransformerDeployer/NO_CODE');
|
||||||
|
|
||||||
|
bytes memory extcode = new bytes(size);
|
||||||
|
assembly {
|
||||||
|
extcodecopy(target, add(extcode, 32), 0, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for any reachable, impermissible opcodes.
|
||||||
|
bool reachable = true;
|
||||||
|
for (uint256 i = 0; i < extcode.length; i++) {
|
||||||
|
uint8 op = uint8(extcode[i]);
|
||||||
|
|
||||||
|
// If the opcode is a PUSH, skip over the push data.
|
||||||
|
if (op > 95 && op < 128) { // pushN
|
||||||
|
i += (op - 95);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reachable) {
|
||||||
|
// If execution is halted, mark subsequent opcodes unreachable.
|
||||||
|
if (
|
||||||
|
op == 254 || // invalid
|
||||||
|
op == 243 || // return
|
||||||
|
op == 253 || // revert
|
||||||
|
op == 86 || // jump
|
||||||
|
op == 0 // stop
|
||||||
|
) {
|
||||||
|
reachable = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If opcode is impermissible, contract is unsafe.
|
||||||
|
if (
|
||||||
|
op == 242 || // callcode
|
||||||
|
op == 244 || // delegatecall
|
||||||
|
op == 255 || // selfdestruct
|
||||||
|
op == 240 || // create
|
||||||
|
op == 245 || // create2
|
||||||
|
op == 84 || // sload
|
||||||
|
op == 85 // sstore
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (op == 91) { // jumpdest
|
||||||
|
// After a JUMPDEST, opcodes are reachable again.
|
||||||
|
reachable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // No impermissible opcodes found.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -20,11 +20,10 @@ pragma solidity ^0.6.5;
|
|||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
import "./libs/LibSignature.sol";
|
||||||
|
|
||||||
/// @dev Meta-transactions feature.
|
/// @dev Meta-transactions feature.
|
||||||
interface IMetaTransactionsFeature {
|
interface IMetaTransactionsFeature {
|
||||||
|
|
||||||
/// @dev Describes an exchange proxy meta transaction.
|
/// @dev Describes an exchange proxy meta transaction.
|
||||||
struct MetaTransactionData {
|
struct MetaTransactionData {
|
||||||
// Signer of meta-transaction. On whose behalf to execute the MTX.
|
// Signer of meta-transaction. On whose behalf to execute the MTX.
|
||||||
@@ -68,7 +67,7 @@ interface IMetaTransactionsFeature {
|
|||||||
/// @return returnResult The ABI-encoded result of the underlying call.
|
/// @return returnResult The ABI-encoded result of the underlying call.
|
||||||
function executeMetaTransaction(
|
function executeMetaTransaction(
|
||||||
MetaTransactionData calldata mtx,
|
MetaTransactionData calldata mtx,
|
||||||
bytes calldata signature
|
LibSignature.Signature calldata signature
|
||||||
)
|
)
|
||||||
external
|
external
|
||||||
payable
|
payable
|
||||||
@@ -80,7 +79,7 @@ interface IMetaTransactionsFeature {
|
|||||||
/// @return returnResults The ABI-encoded results of the underlying calls.
|
/// @return returnResults The ABI-encoded results of the underlying calls.
|
||||||
function batchExecuteMetaTransactions(
|
function batchExecuteMetaTransactions(
|
||||||
MetaTransactionData[] calldata mtxs,
|
MetaTransactionData[] calldata mtxs,
|
||||||
bytes[] calldata signatures
|
LibSignature.Signature[] calldata signatures
|
||||||
)
|
)
|
||||||
external
|
external
|
||||||
payable
|
payable
|
||||||
@@ -88,14 +87,14 @@ interface IMetaTransactionsFeature {
|
|||||||
|
|
||||||
/// @dev Execute a meta-transaction via `sender`. Privileged variant.
|
/// @dev Execute a meta-transaction via `sender`. Privileged variant.
|
||||||
/// Only callable from within.
|
/// Only callable from within.
|
||||||
/// @param sender Who is executing the meta-transaction..
|
/// @param sender Who is executing the meta-transaction.
|
||||||
/// @param mtx The meta-transaction.
|
/// @param mtx The meta-transaction.
|
||||||
/// @param signature The signature by `mtx.signer`.
|
/// @param signature The signature by `mtx.signer`.
|
||||||
/// @return returnResult The ABI-encoded result of the underlying call.
|
/// @return returnResult The ABI-encoded result of the underlying call.
|
||||||
function _executeMetaTransaction(
|
function _executeMetaTransaction(
|
||||||
address sender,
|
address sender,
|
||||||
MetaTransactionData calldata mtx,
|
MetaTransactionData memory mtx,
|
||||||
bytes calldata signature
|
LibSignature.Signature memory signature
|
||||||
)
|
)
|
||||||
external
|
external
|
||||||
payable
|
payable
|
||||||
|
@@ -0,0 +1,349 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
import "./libs/LibSignature.sol";
|
||||||
|
import "./libs/LibNativeOrder.sol";
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev Feature for interacting with limit orders.
|
||||||
|
interface INativeOrdersFeature {
|
||||||
|
|
||||||
|
/// @dev Emitted whenever a `LimitOrder` is filled.
|
||||||
|
/// @param orderHash The canonical hash of the order.
|
||||||
|
/// @param maker The maker of the order.
|
||||||
|
/// @param taker The taker of the order.
|
||||||
|
/// @param feeRecipient Fee recipient of the order.
|
||||||
|
/// @param takerTokenFilledAmount How much taker token was filled.
|
||||||
|
/// @param makerTokenFilledAmount How much maker token was filled.
|
||||||
|
/// @param protocolFeePaid How much protocol fee was paid.
|
||||||
|
/// @param pool The fee pool associated with this order.
|
||||||
|
event LimitOrderFilled(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address maker,
|
||||||
|
address taker,
|
||||||
|
address feeRecipient,
|
||||||
|
address makerToken,
|
||||||
|
address takerToken,
|
||||||
|
uint128 takerTokenFilledAmount,
|
||||||
|
uint128 makerTokenFilledAmount,
|
||||||
|
uint128 takerTokenFeeFilledAmount,
|
||||||
|
uint256 protocolFeePaid,
|
||||||
|
bytes32 pool
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @dev Emitted whenever an `RfqOrder` is filled.
|
||||||
|
/// @param orderHash The canonical hash of the order.
|
||||||
|
/// @param maker The maker of the order.
|
||||||
|
/// @param taker The taker of the order.
|
||||||
|
/// @param takerTokenFilledAmount How much taker token was filled.
|
||||||
|
/// @param makerTokenFilledAmount How much maker token was filled.
|
||||||
|
/// @param pool The fee pool associated with this order.
|
||||||
|
event RfqOrderFilled(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address maker,
|
||||||
|
address taker,
|
||||||
|
address makerToken,
|
||||||
|
address takerToken,
|
||||||
|
uint128 takerTokenFilledAmount,
|
||||||
|
uint128 makerTokenFilledAmount,
|
||||||
|
bytes32 pool
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @dev Emitted whenever a limit or RFQ order is cancelled.
|
||||||
|
/// @param orderHash The canonical hash of the order.
|
||||||
|
/// @param maker The order maker.
|
||||||
|
event OrderCancelled(
|
||||||
|
bytes32 orderHash,
|
||||||
|
address maker
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @dev Emitted whenever Limit orders are cancelled by pair by a maker.
|
||||||
|
/// @param maker The maker of the order.
|
||||||
|
/// @param makerToken The maker token in a pair for the orders cancelled.
|
||||||
|
/// @param takerToken The taker token in a pair for the orders cancelled.
|
||||||
|
/// @param minValidSalt The new minimum valid salt an order with this pair must
|
||||||
|
/// have.
|
||||||
|
event PairCancelledLimitOrders(
|
||||||
|
address maker,
|
||||||
|
address makerToken,
|
||||||
|
address takerToken,
|
||||||
|
uint256 minValidSalt
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @dev Emitted whenever RFQ orders are cancelled by pair by a maker.
|
||||||
|
/// @param maker The maker of the order.
|
||||||
|
/// @param makerToken The maker token in a pair for the orders cancelled.
|
||||||
|
/// @param takerToken The taker token in a pair for the orders cancelled.
|
||||||
|
/// @param minValidSalt The new minimum valid salt an order with this pair must
|
||||||
|
/// have.
|
||||||
|
event PairCancelledRfqOrders(
|
||||||
|
address maker,
|
||||||
|
address makerToken,
|
||||||
|
address takerToken,
|
||||||
|
uint256 minValidSalt
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @dev Emitted when new addresses are allowed or disallowed to fill
|
||||||
|
/// orders with a given txOrigin.
|
||||||
|
/// @param origin The address doing the allowing.
|
||||||
|
/// @param addrs The address being allowed/disallowed.
|
||||||
|
/// @param allowed Indicates whether the address should be allowed.
|
||||||
|
event RfqOrderOriginsAllowed(
|
||||||
|
address origin,
|
||||||
|
address[] addrs,
|
||||||
|
bool allowed
|
||||||
|
);
|
||||||
|
|
||||||
|
/// @dev Transfers protocol fees from the `FeeCollector` pools into
|
||||||
|
/// the staking contract.
|
||||||
|
/// @param poolIds Staking pool IDs
|
||||||
|
function transferProtocolFeesForPools(bytes32[] calldata poolIds)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Fill a limit order. The taker and sender will be the caller.
|
||||||
|
/// @param order The limit order. ETH protocol fees can be
|
||||||
|
/// attached to this call. Any unspent ETH will be refunded to
|
||||||
|
/// the caller.
|
||||||
|
/// @param signature The order signature.
|
||||||
|
/// @param takerTokenFillAmount Maximum taker token amount to fill this order with.
|
||||||
|
/// @return takerTokenFilledAmount How much maker token was filled.
|
||||||
|
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||||
|
function fillLimitOrder(
|
||||||
|
LibNativeOrder.LimitOrder calldata order,
|
||||||
|
LibSignature.Signature calldata signature,
|
||||||
|
uint128 takerTokenFillAmount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
|
|
||||||
|
/// @dev Fill an RFQ order for up to `takerTokenFillAmount` taker tokens.
|
||||||
|
/// The taker will be the caller.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
/// @param signature The order signature.
|
||||||
|
/// @param takerTokenFillAmount Maximum taker token amount to fill this order with.
|
||||||
|
/// @return takerTokenFilledAmount How much maker token was filled.
|
||||||
|
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||||
|
function fillRfqOrder(
|
||||||
|
LibNativeOrder.RfqOrder calldata order,
|
||||||
|
LibSignature.Signature calldata signature,
|
||||||
|
uint128 takerTokenFillAmount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
|
|
||||||
|
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
||||||
|
/// The taker will be the caller. ETH protocol fees can be
|
||||||
|
/// attached to this call. Any unspent ETH will be refunded to
|
||||||
|
/// the caller.
|
||||||
|
/// @param order The limit order.
|
||||||
|
/// @param signature The order signature.
|
||||||
|
/// @param takerTokenFillAmount How much taker token to fill this order with.
|
||||||
|
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||||
|
function fillOrKillLimitOrder(
|
||||||
|
LibNativeOrder.LimitOrder calldata order,
|
||||||
|
LibSignature.Signature calldata signature,
|
||||||
|
uint128 takerTokenFillAmount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (uint128 makerTokenFilledAmount);
|
||||||
|
|
||||||
|
/// @dev Fill an RFQ order for exactly `takerTokenFillAmount` taker tokens.
|
||||||
|
/// The taker will be the caller.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
/// @param signature The order signature.
|
||||||
|
/// @param takerTokenFillAmount How much taker token to fill this order with.
|
||||||
|
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||||
|
function fillOrKillRfqOrder(
|
||||||
|
LibNativeOrder.RfqOrder calldata order,
|
||||||
|
LibSignature.Signature calldata signature,
|
||||||
|
uint128 takerTokenFillAmount
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (uint128 makerTokenFilledAmount);
|
||||||
|
|
||||||
|
/// @dev Fill a limit order. Internal variant. ETH protocol fees can be
|
||||||
|
/// attached to this call. Any unspent ETH will be refunded to
|
||||||
|
/// `msg.sender` (not `sender`).
|
||||||
|
/// @param order The limit order.
|
||||||
|
/// @param signature The order signature.
|
||||||
|
/// @param takerTokenFillAmount Maximum taker token to fill this order with.
|
||||||
|
/// @param taker The order taker.
|
||||||
|
/// @param sender The order sender.
|
||||||
|
/// @return takerTokenFilledAmount How much maker token was filled.
|
||||||
|
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||||
|
function _fillLimitOrder(
|
||||||
|
LibNativeOrder.LimitOrder calldata order,
|
||||||
|
LibSignature.Signature calldata signature,
|
||||||
|
uint128 takerTokenFillAmount,
|
||||||
|
address taker,
|
||||||
|
address sender
|
||||||
|
)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
|
|
||||||
|
/// @dev Fill an RFQ order. Internal variant.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
/// @param signature The order signature.
|
||||||
|
/// @param takerTokenFillAmount Maximum taker token to fill this order with.
|
||||||
|
/// @param taker The order taker.
|
||||||
|
/// @return takerTokenFilledAmount How much maker token was filled.
|
||||||
|
/// @return makerTokenFilledAmount How much maker token was filled.
|
||||||
|
function _fillRfqOrder(
|
||||||
|
LibNativeOrder.RfqOrder calldata order,
|
||||||
|
LibSignature.Signature calldata signature,
|
||||||
|
uint128 takerTokenFillAmount,
|
||||||
|
address taker
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount);
|
||||||
|
|
||||||
|
/// @dev Cancel a single limit order. The caller must be the maker.
|
||||||
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
|
/// @param order The limit order.
|
||||||
|
function cancelLimitOrder(LibNativeOrder.LimitOrder calldata order)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel a single RFQ order. The caller must be the maker.
|
||||||
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
function cancelRfqOrder(LibNativeOrder.RfqOrder calldata order)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Mark what tx.origin addresses are allowed to fill an order that
|
||||||
|
/// specifies the message sender as its txOrigin.
|
||||||
|
/// @param origins An array of origin addresses to update.
|
||||||
|
/// @param allowed True to register, false to unregister.
|
||||||
|
function registerAllowedRfqOrigins(address[] memory origins, bool allowed)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel multiple limit orders. The caller must be the maker.
|
||||||
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
|
/// @param orders The limit orders.
|
||||||
|
function batchCancelLimitOrders(LibNativeOrder.LimitOrder[] calldata orders)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel multiple RFQ orders. The caller must be the maker.
|
||||||
|
/// Silently succeeds if the order has already been cancelled.
|
||||||
|
/// @param orders The RFQ orders.
|
||||||
|
function batchCancelRfqOrders(LibNativeOrder.RfqOrder[] calldata orders)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel all limit orders for a given maker and pair with a salt less
|
||||||
|
/// than the value provided. The caller must be the maker. Subsequent
|
||||||
|
/// calls to this function with the same caller and pair require the
|
||||||
|
/// new salt to be >= the old salt.
|
||||||
|
/// @param makerToken The maker token.
|
||||||
|
/// @param takerToken The taker token.
|
||||||
|
/// @param minValidSalt The new minimum valid salt.
|
||||||
|
function cancelPairLimitOrders(
|
||||||
|
IERC20TokenV06 makerToken,
|
||||||
|
IERC20TokenV06 takerToken,
|
||||||
|
uint256 minValidSalt
|
||||||
|
)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel all limit orders for a given maker and pair with a salt less
|
||||||
|
/// than the value provided. The caller must be the maker. Subsequent
|
||||||
|
/// calls to this function with the same caller and pair require the
|
||||||
|
/// new salt to be >= the old salt.
|
||||||
|
/// @param makerTokens The maker tokens.
|
||||||
|
/// @param takerTokens The taker tokens.
|
||||||
|
/// @param minValidSalts The new minimum valid salts.
|
||||||
|
function batchCancelPairLimitOrders(
|
||||||
|
IERC20TokenV06[] calldata makerTokens,
|
||||||
|
IERC20TokenV06[] calldata takerTokens,
|
||||||
|
uint256[] calldata minValidSalts
|
||||||
|
)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less
|
||||||
|
/// than the value provided. The caller must be the maker. Subsequent
|
||||||
|
/// calls to this function with the same caller and pair require the
|
||||||
|
/// new salt to be >= the old salt.
|
||||||
|
/// @param makerToken The maker token.
|
||||||
|
/// @param takerToken The taker token.
|
||||||
|
/// @param minValidSalt The new minimum valid salt.
|
||||||
|
function cancelPairRfqOrders(
|
||||||
|
IERC20TokenV06 makerToken,
|
||||||
|
IERC20TokenV06 takerToken,
|
||||||
|
uint256 minValidSalt
|
||||||
|
)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Cancel all RFQ orders for a given maker and pair with a salt less
|
||||||
|
/// than the value provided. The caller must be the maker. Subsequent
|
||||||
|
/// calls to this function with the same caller and pair require the
|
||||||
|
/// new salt to be >= the old salt.
|
||||||
|
/// @param makerTokens The maker tokens.
|
||||||
|
/// @param takerTokens The taker tokens.
|
||||||
|
/// @param minValidSalts The new minimum valid salts.
|
||||||
|
function batchCancelPairRfqOrders(
|
||||||
|
IERC20TokenV06[] calldata makerTokens,
|
||||||
|
IERC20TokenV06[] calldata takerTokens,
|
||||||
|
uint256[] calldata minValidSalts
|
||||||
|
)
|
||||||
|
external;
|
||||||
|
|
||||||
|
/// @dev Get the order info for a limit order.
|
||||||
|
/// @param order The limit order.
|
||||||
|
/// @return orderInfo Info about the order.
|
||||||
|
function getLimitOrderInfo(LibNativeOrder.LimitOrder calldata order)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (LibNativeOrder.OrderInfo memory orderInfo);
|
||||||
|
|
||||||
|
/// @dev Get the order info for an RFQ order.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
/// @return orderInfo Info about the order.
|
||||||
|
function getRfqOrderInfo(LibNativeOrder.RfqOrder calldata order)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (LibNativeOrder.OrderInfo memory orderInfo);
|
||||||
|
|
||||||
|
/// @dev Get the canonical hash of a limit order.
|
||||||
|
/// @param order The limit order.
|
||||||
|
/// @return orderHash The order hash.
|
||||||
|
function getLimitOrderHash(LibNativeOrder.LimitOrder calldata order)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (bytes32 orderHash);
|
||||||
|
|
||||||
|
/// @dev Get the canonical hash of an RFQ order.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
/// @return orderHash The order hash.
|
||||||
|
function getRfqOrderHash(LibNativeOrder.RfqOrder calldata order)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (bytes32 orderHash);
|
||||||
|
|
||||||
|
/// @dev Get the protocol fee multiplier. This should be multiplied by the
|
||||||
|
/// gas price to arrive at the required protocol fee to fill a native order.
|
||||||
|
/// @return multiplier The protocol fee multiplier.
|
||||||
|
function getProtocolFeeMultiplier()
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint32 multiplier);
|
||||||
|
|
||||||
|
}
|
@@ -57,12 +57,4 @@ interface ISimpleFunctionRegistryFeature {
|
|||||||
external
|
external
|
||||||
view
|
view
|
||||||
returns (address impl);
|
returns (address impl);
|
||||||
|
|
||||||
/// @dev Get the implementation contract of a registered function.
|
|
||||||
/// @param selector The function selector.
|
|
||||||
/// @return impl The implementation contract address.
|
|
||||||
function getFunctionImplementation(bytes4 selector)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (address impl);
|
|
||||||
}
|
}
|
||||||
|
@@ -58,10 +58,6 @@ interface ITransformERC20Feature {
|
|||||||
// The transformations to execute on the token balance(s)
|
// The transformations to execute on the token balance(s)
|
||||||
// in sequence.
|
// in sequence.
|
||||||
Transformation[] transformations;
|
Transformation[] transformations;
|
||||||
// The hash of the calldata for the `transformERC20()` call.
|
|
||||||
bytes32 callDataHash;
|
|
||||||
// The signature for `callDataHash` signed by `getQuoteSigner()`.
|
|
||||||
bytes callDataSignature;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Raised upon a successful `transformERC20`.
|
/// @dev Raised upon a successful `transformERC20`.
|
||||||
|
@@ -26,16 +26,17 @@ import "../errors/LibLiquidityProviderRichErrors.sol";
|
|||||||
import "../external/ILiquidityProviderSandbox.sol";
|
import "../external/ILiquidityProviderSandbox.sol";
|
||||||
import "../external/LiquidityProviderSandbox.sol";
|
import "../external/LiquidityProviderSandbox.sol";
|
||||||
import "../fixins/FixinCommon.sol";
|
import "../fixins/FixinCommon.sol";
|
||||||
|
import "../fixins/FixinTokenSpender.sol";
|
||||||
import "../migrations/LibMigrate.sol";
|
import "../migrations/LibMigrate.sol";
|
||||||
import "./IFeature.sol";
|
import "./IFeature.sol";
|
||||||
import "./ILiquidityProviderFeature.sol";
|
import "./ILiquidityProviderFeature.sol";
|
||||||
import "./libs/LibTokenSpender.sol";
|
|
||||||
|
|
||||||
|
|
||||||
contract LiquidityProviderFeature is
|
contract LiquidityProviderFeature is
|
||||||
IFeature,
|
IFeature,
|
||||||
ILiquidityProviderFeature,
|
ILiquidityProviderFeature,
|
||||||
FixinCommon
|
FixinCommon,
|
||||||
|
FixinTokenSpender
|
||||||
{
|
{
|
||||||
using LibSafeMathV06 for uint256;
|
using LibSafeMathV06 for uint256;
|
||||||
using LibRichErrorsV06 for bytes;
|
using LibRichErrorsV06 for bytes;
|
||||||
@@ -43,7 +44,7 @@ contract LiquidityProviderFeature is
|
|||||||
/// @dev Name of this feature.
|
/// @dev Name of this feature.
|
||||||
string public constant override FEATURE_NAME = "LiquidityProviderFeature";
|
string public constant override FEATURE_NAME = "LiquidityProviderFeature";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 2);
|
||||||
|
|
||||||
/// @dev ETH pseudo-token address.
|
/// @dev ETH pseudo-token address.
|
||||||
address constant internal ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
address constant internal ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||||
@@ -60,11 +61,12 @@ contract LiquidityProviderFeature is
|
|||||||
address recipient
|
address recipient
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor(address zeroEx)
|
constructor(LiquidityProviderSandbox sandbox_, bytes32 greedyTokensBloomFilter)
|
||||||
public
|
public
|
||||||
FixinCommon()
|
FixinCommon()
|
||||||
|
FixinTokenSpender(greedyTokensBloomFilter)
|
||||||
{
|
{
|
||||||
sandbox = new LiquidityProviderSandbox(zeroEx);
|
sandbox = sandbox_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Initialize and register this feature.
|
/// @dev Initialize and register this feature.
|
||||||
@@ -109,10 +111,14 @@ contract LiquidityProviderFeature is
|
|||||||
recipient = msg.sender;
|
recipient = msg.sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputToken == ETH_TOKEN_ADDRESS) {
|
// Forward all attached ETH to the provider.
|
||||||
provider.transfer(sellAmount);
|
if (msg.value > 0) {
|
||||||
} else {
|
provider.transfer(msg.value);
|
||||||
LibTokenSpender.spendERC20Tokens(
|
}
|
||||||
|
|
||||||
|
if (inputToken != ETH_TOKEN_ADDRESS) {
|
||||||
|
// Transfer input ERC20 tokens to the provider.
|
||||||
|
_transferERC20Tokens(
|
||||||
IERC20TokenV06(inputToken),
|
IERC20TokenV06(inputToken),
|
||||||
msg.sender,
|
msg.sender,
|
||||||
provider,
|
provider,
|
||||||
|
@@ -25,16 +25,16 @@ import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
|||||||
import "../errors/LibMetaTransactionsRichErrors.sol";
|
import "../errors/LibMetaTransactionsRichErrors.sol";
|
||||||
import "../fixins/FixinCommon.sol";
|
import "../fixins/FixinCommon.sol";
|
||||||
import "../fixins/FixinReentrancyGuard.sol";
|
import "../fixins/FixinReentrancyGuard.sol";
|
||||||
|
import "../fixins/FixinTokenSpender.sol";
|
||||||
import "../fixins/FixinEIP712.sol";
|
import "../fixins/FixinEIP712.sol";
|
||||||
import "../migrations/LibMigrate.sol";
|
import "../migrations/LibMigrate.sol";
|
||||||
import "../storage/LibMetaTransactionsStorage.sol";
|
import "../storage/LibMetaTransactionsStorage.sol";
|
||||||
import "./libs/LibSignedCallData.sol";
|
|
||||||
import "./IMetaTransactionsFeature.sol";
|
import "./IMetaTransactionsFeature.sol";
|
||||||
import "./ITransformERC20Feature.sol";
|
import "./ITransformERC20Feature.sol";
|
||||||
|
import "./libs/LibSignature.sol";
|
||||||
import "./ISignatureValidatorFeature.sol";
|
import "./ISignatureValidatorFeature.sol";
|
||||||
import "./IFeature.sol";
|
import "./IFeature.sol";
|
||||||
import "./libs/LibTokenSpender.sol";
|
import "./INativeOrdersFeature.sol";
|
||||||
|
|
||||||
|
|
||||||
/// @dev MetaTransactions feature.
|
/// @dev MetaTransactions feature.
|
||||||
contract MetaTransactionsFeature is
|
contract MetaTransactionsFeature is
|
||||||
@@ -42,13 +42,13 @@ contract MetaTransactionsFeature is
|
|||||||
IMetaTransactionsFeature,
|
IMetaTransactionsFeature,
|
||||||
FixinCommon,
|
FixinCommon,
|
||||||
FixinReentrancyGuard,
|
FixinReentrancyGuard,
|
||||||
FixinEIP712
|
FixinEIP712,
|
||||||
|
FixinTokenSpender
|
||||||
{
|
{
|
||||||
using LibBytesV06 for bytes;
|
using LibBytesV06 for bytes;
|
||||||
using LibRichErrorsV06 for bytes;
|
using LibRichErrorsV06 for bytes;
|
||||||
|
|
||||||
/// @dev Intermediate state vars used by `_executeMetaTransactionPrivate()`
|
/// @dev Describes the state of a meta transaction.
|
||||||
/// to avoid stack overflows.
|
|
||||||
struct ExecuteState {
|
struct ExecuteState {
|
||||||
// Sender of the meta-transaction.
|
// Sender of the meta-transaction.
|
||||||
address sender;
|
address sender;
|
||||||
@@ -57,7 +57,7 @@ contract MetaTransactionsFeature is
|
|||||||
// The meta-transaction data.
|
// The meta-transaction data.
|
||||||
MetaTransactionData mtx;
|
MetaTransactionData mtx;
|
||||||
// The meta-transaction signature (by `mtx.signer`).
|
// The meta-transaction signature (by `mtx.signer`).
|
||||||
bytes signature;
|
LibSignature.Signature signature;
|
||||||
// The selector of the function being called.
|
// The selector of the function being called.
|
||||||
bytes4 selector;
|
bytes4 selector;
|
||||||
// The ETH balance of this contract before performing the call.
|
// The ETH balance of this contract before performing the call.
|
||||||
@@ -78,7 +78,7 @@ contract MetaTransactionsFeature is
|
|||||||
/// @dev Name of this feature.
|
/// @dev Name of this feature.
|
||||||
string public constant override FEATURE_NAME = "MetaTransactions";
|
string public constant override FEATURE_NAME = "MetaTransactions";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
|
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
|
||||||
/// @dev EIP712 typehash of the `MetaTransactionData` struct.
|
/// @dev EIP712 typehash of the `MetaTransactionData` struct.
|
||||||
bytes32 public immutable MTX_EIP712_TYPEHASH = keccak256(
|
bytes32 public immutable MTX_EIP712_TYPEHASH = keccak256(
|
||||||
"MetaTransactionData("
|
"MetaTransactionData("
|
||||||
@@ -105,10 +105,11 @@ contract MetaTransactionsFeature is
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(address zeroExAddress)
|
constructor(address zeroExAddress, bytes32 greedyTokensBloomFilter)
|
||||||
public
|
public
|
||||||
FixinCommon()
|
FixinCommon()
|
||||||
FixinEIP712(zeroExAddress)
|
FixinEIP712(zeroExAddress)
|
||||||
|
FixinTokenSpender(greedyTokensBloomFilter)
|
||||||
{
|
{
|
||||||
// solhint-disable-next-line no-empty-blocks
|
// solhint-disable-next-line no-empty-blocks
|
||||||
}
|
}
|
||||||
@@ -135,7 +136,7 @@ contract MetaTransactionsFeature is
|
|||||||
/// @return returnResult The ABI-encoded result of the underlying call.
|
/// @return returnResult The ABI-encoded result of the underlying call.
|
||||||
function executeMetaTransaction(
|
function executeMetaTransaction(
|
||||||
MetaTransactionData memory mtx,
|
MetaTransactionData memory mtx,
|
||||||
bytes memory signature
|
LibSignature.Signature memory signature
|
||||||
)
|
)
|
||||||
public
|
public
|
||||||
payable
|
payable
|
||||||
@@ -144,11 +145,13 @@ contract MetaTransactionsFeature is
|
|||||||
refundsAttachedEth
|
refundsAttachedEth
|
||||||
returns (bytes memory returnResult)
|
returns (bytes memory returnResult)
|
||||||
{
|
{
|
||||||
returnResult = _executeMetaTransactionPrivate(
|
ExecuteState memory state;
|
||||||
msg.sender,
|
state.sender = msg.sender;
|
||||||
mtx,
|
state.mtx = mtx;
|
||||||
signature
|
state.hash = getMetaTransactionHash(mtx);
|
||||||
);
|
state.signature = signature;
|
||||||
|
|
||||||
|
returnResult = _executeMetaTransactionPrivate(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Execute multiple meta-transactions.
|
/// @dev Execute multiple meta-transactions.
|
||||||
@@ -157,7 +160,7 @@ contract MetaTransactionsFeature is
|
|||||||
/// @return returnResults The ABI-encoded results of the underlying calls.
|
/// @return returnResults The ABI-encoded results of the underlying calls.
|
||||||
function batchExecuteMetaTransactions(
|
function batchExecuteMetaTransactions(
|
||||||
MetaTransactionData[] memory mtxs,
|
MetaTransactionData[] memory mtxs,
|
||||||
bytes[] memory signatures
|
LibSignature.Signature[] memory signatures
|
||||||
)
|
)
|
||||||
public
|
public
|
||||||
payable
|
payable
|
||||||
@@ -174,11 +177,13 @@ contract MetaTransactionsFeature is
|
|||||||
}
|
}
|
||||||
returnResults = new bytes[](mtxs.length);
|
returnResults = new bytes[](mtxs.length);
|
||||||
for (uint256 i = 0; i < mtxs.length; ++i) {
|
for (uint256 i = 0; i < mtxs.length; ++i) {
|
||||||
returnResults[i] = _executeMetaTransactionPrivate(
|
ExecuteState memory state;
|
||||||
msg.sender,
|
state.sender = msg.sender;
|
||||||
mtxs[i],
|
state.mtx = mtxs[i];
|
||||||
signatures[i]
|
state.hash = getMetaTransactionHash(mtxs[i]);
|
||||||
);
|
state.signature = signatures[i];
|
||||||
|
|
||||||
|
returnResults[i] = _executeMetaTransactionPrivate(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +196,7 @@ contract MetaTransactionsFeature is
|
|||||||
function _executeMetaTransaction(
|
function _executeMetaTransaction(
|
||||||
address sender,
|
address sender,
|
||||||
MetaTransactionData memory mtx,
|
MetaTransactionData memory mtx,
|
||||||
bytes memory signature
|
LibSignature.Signature memory signature
|
||||||
)
|
)
|
||||||
public
|
public
|
||||||
payable
|
payable
|
||||||
@@ -199,7 +204,13 @@ contract MetaTransactionsFeature is
|
|||||||
onlySelf
|
onlySelf
|
||||||
returns (bytes memory returnResult)
|
returns (bytes memory returnResult)
|
||||||
{
|
{
|
||||||
return _executeMetaTransactionPrivate(sender, mtx, signature);
|
ExecuteState memory state;
|
||||||
|
state.sender = sender;
|
||||||
|
state.mtx = mtx;
|
||||||
|
state.hash = getMetaTransactionHash(mtx);
|
||||||
|
state.signature = signature;
|
||||||
|
|
||||||
|
return _executeMetaTransactionPrivate(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Get the block at which a meta-transaction has been executed.
|
/// @dev Get the block at which a meta-transaction has been executed.
|
||||||
@@ -251,24 +262,13 @@ contract MetaTransactionsFeature is
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Execute a meta-transaction by `sender`. Low-level, hidden variant.
|
/// @dev Execute a meta-transaction by `sender`. Low-level, hidden variant.
|
||||||
/// @param sender Who is executing the meta-transaction..
|
/// @param state The `ExecuteState` for this metatransaction, with `sender`,
|
||||||
/// @param mtx The meta-transaction.
|
/// `hash`, `mtx`, and `signature` fields filled.
|
||||||
/// @param signature The signature by `mtx.signer`.
|
|
||||||
/// @return returnResult The ABI-encoded result of the underlying call.
|
/// @return returnResult The ABI-encoded result of the underlying call.
|
||||||
function _executeMetaTransactionPrivate(
|
function _executeMetaTransactionPrivate(ExecuteState memory state)
|
||||||
address sender,
|
|
||||||
MetaTransactionData memory mtx,
|
|
||||||
bytes memory signature
|
|
||||||
)
|
|
||||||
private
|
private
|
||||||
returns (bytes memory returnResult)
|
returns (bytes memory returnResult)
|
||||||
{
|
{
|
||||||
ExecuteState memory state;
|
|
||||||
state.sender = sender;
|
|
||||||
state.hash = getMetaTransactionHash(mtx);
|
|
||||||
state.mtx = mtx;
|
|
||||||
state.signature = signature;
|
|
||||||
|
|
||||||
_validateMetaTransaction(state);
|
_validateMetaTransaction(state);
|
||||||
|
|
||||||
// Mark the transaction executed by storing the block at which it was executed.
|
// Mark the transaction executed by storing the block at which it was executed.
|
||||||
@@ -278,19 +278,23 @@ contract MetaTransactionsFeature is
|
|||||||
.mtxHashToExecutedBlockNumber[state.hash] = block.number;
|
.mtxHashToExecutedBlockNumber[state.hash] = block.number;
|
||||||
|
|
||||||
// Pay the fee to the sender.
|
// Pay the fee to the sender.
|
||||||
if (mtx.feeAmount > 0) {
|
if (state.mtx.feeAmount > 0) {
|
||||||
LibTokenSpender.spendERC20Tokens(
|
_transferERC20Tokens(
|
||||||
mtx.feeToken,
|
state.mtx.feeToken,
|
||||||
mtx.signer,
|
state.mtx.signer,
|
||||||
sender,
|
state.sender,
|
||||||
mtx.feeAmount
|
state.mtx.feeAmount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the call based on the selector.
|
// Execute the call based on the selector.
|
||||||
state.selector = mtx.callData.readBytes4(0);
|
state.selector = state.mtx.callData.readBytes4(0);
|
||||||
if (state.selector == ITransformERC20Feature.transformERC20.selector) {
|
if (state.selector == ITransformERC20Feature.transformERC20.selector) {
|
||||||
returnResult = _executeTransformERC20Call(state);
|
returnResult = _executeTransformERC20Call(state);
|
||||||
|
} else if (state.selector == INativeOrdersFeature.fillLimitOrder.selector) {
|
||||||
|
returnResult = _executeFillLimitOrderCall(state);
|
||||||
|
} else if (state.selector == INativeOrdersFeature.fillRfqOrder.selector) {
|
||||||
|
returnResult = _executeFillRfqOrderCall(state);
|
||||||
} else {
|
} else {
|
||||||
LibMetaTransactionsRichErrors
|
LibMetaTransactionsRichErrors
|
||||||
.MetaTransactionUnsupportedFunctionError(state.hash, state.selector)
|
.MetaTransactionUnsupportedFunctionError(state.hash, state.selector)
|
||||||
@@ -299,8 +303,8 @@ contract MetaTransactionsFeature is
|
|||||||
emit MetaTransactionExecuted(
|
emit MetaTransactionExecuted(
|
||||||
state.hash,
|
state.hash,
|
||||||
state.selector,
|
state.selector,
|
||||||
mtx.signer,
|
state.mtx.signer,
|
||||||
mtx.sender
|
state.mtx.sender
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,18 +351,17 @@ contract MetaTransactionsFeature is
|
|||||||
state.mtx.value
|
state.mtx.value
|
||||||
).rrevert();
|
).rrevert();
|
||||||
}
|
}
|
||||||
// Must be signed by signer.
|
|
||||||
try
|
if (LibSignature.getSignerOfHash(state.hash, state.signature) !=
|
||||||
ISignatureValidatorFeature(address(this))
|
state.mtx.signer) {
|
||||||
.validateHashSignature(state.hash, state.mtx.signer, state.signature)
|
LibSignatureRichErrors.SignatureValidationError(
|
||||||
{}
|
LibSignatureRichErrors.SignatureValidationErrorCodes.WRONG_SIGNER,
|
||||||
catch (bytes memory err) {
|
state.hash,
|
||||||
LibMetaTransactionsRichErrors
|
state.mtx.signer,
|
||||||
.MetaTransactionInvalidSignatureError(
|
// TODO: Remove this field from SignatureValidationError
|
||||||
state.hash,
|
// when rich reverts are part of the protocol repo.
|
||||||
state.signature,
|
""
|
||||||
err
|
).rrevert();
|
||||||
).rrevert();
|
|
||||||
}
|
}
|
||||||
// Transaction must not have been already executed.
|
// Transaction must not have been already executed.
|
||||||
state.executedBlockNumber = LibMetaTransactionsStorage
|
state.executedBlockNumber = LibMetaTransactionsStorage
|
||||||
@@ -429,10 +432,6 @@ contract MetaTransactionsFeature is
|
|||||||
// Decode call args for `ITransformERC20Feature.transformERC20()` as a struct.
|
// Decode call args for `ITransformERC20Feature.transformERC20()` as a struct.
|
||||||
args = abi.decode(encodedStructArgs, (ExternalTransformERC20Args));
|
args = abi.decode(encodedStructArgs, (ExternalTransformERC20Args));
|
||||||
}
|
}
|
||||||
// Parse the signature and hash out of the calldata so `_transformERC20()`
|
|
||||||
// can authenticate it.
|
|
||||||
(bytes32 callDataHash, bytes memory callDataSignature) =
|
|
||||||
LibSignedCallData.parseCallData(state.mtx.callData);
|
|
||||||
// Call `ITransformERC20Feature._transformERC20()` (internal variant).
|
// Call `ITransformERC20Feature._transformERC20()` (internal variant).
|
||||||
return _callSelf(
|
return _callSelf(
|
||||||
state.hash,
|
state.hash,
|
||||||
@@ -444,15 +443,95 @@ contract MetaTransactionsFeature is
|
|||||||
outputToken: args.outputToken,
|
outputToken: args.outputToken,
|
||||||
inputTokenAmount: args.inputTokenAmount,
|
inputTokenAmount: args.inputTokenAmount,
|
||||||
minOutputTokenAmount: args.minOutputTokenAmount,
|
minOutputTokenAmount: args.minOutputTokenAmount,
|
||||||
transformations: args.transformations,
|
transformations: args.transformations
|
||||||
callDataHash: callDataHash,
|
|
||||||
callDataSignature: callDataSignature
|
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
state.mtx.value
|
state.mtx.value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @dev Extract arguments from call data by copying everything after the
|
||||||
|
/// 4-byte selector into a new byte array.
|
||||||
|
/// @param callData The call data from which arguments are to be extracted.
|
||||||
|
/// @return args The extracted arguments as a byte array.
|
||||||
|
function _extractArgumentsFromCallData(
|
||||||
|
bytes memory callData
|
||||||
|
)
|
||||||
|
private
|
||||||
|
pure
|
||||||
|
returns (bytes memory args)
|
||||||
|
{
|
||||||
|
args = new bytes(callData.length - 4);
|
||||||
|
uint256 fromMem;
|
||||||
|
uint256 toMem;
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
fromMem := add(callData, 36) // skip length and 4-byte selector
|
||||||
|
toMem := add(args, 32) // write after length prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
LibBytesV06.memCopy(toMem, fromMem, args.length);
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Execute a `INativeOrdersFeature.fillLimitOrder()` meta-transaction call
|
||||||
|
/// by decoding the call args and translating the call to the internal
|
||||||
|
/// `INativeOrdersFeature._fillLimitOrder()` variant, where we can override
|
||||||
|
/// the taker address.
|
||||||
|
function _executeFillLimitOrderCall(ExecuteState memory state)
|
||||||
|
private
|
||||||
|
returns (bytes memory returnResult)
|
||||||
|
{
|
||||||
|
LibNativeOrder.LimitOrder memory order;
|
||||||
|
LibSignature.Signature memory signature;
|
||||||
|
uint128 takerTokenFillAmount;
|
||||||
|
|
||||||
|
bytes memory args = _extractArgumentsFromCallData(state.mtx.callData);
|
||||||
|
(order, signature, takerTokenFillAmount) = abi.decode(args, (LibNativeOrder.LimitOrder, LibSignature.Signature, uint128));
|
||||||
|
|
||||||
|
return _callSelf(
|
||||||
|
state.hash,
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
INativeOrdersFeature._fillLimitOrder.selector,
|
||||||
|
order,
|
||||||
|
signature,
|
||||||
|
takerTokenFillAmount,
|
||||||
|
state.mtx.signer, // taker is mtx signer
|
||||||
|
msg.sender
|
||||||
|
),
|
||||||
|
state.mtx.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Execute a `INativeOrdersFeature.fillRfqOrder()` meta-transaction call
|
||||||
|
/// by decoding the call args and translating the call to the internal
|
||||||
|
/// `INativeOrdersFeature._fillRfqOrder()` variant, where we can overrideunimpleme
|
||||||
|
/// the taker address.
|
||||||
|
function _executeFillRfqOrderCall(ExecuteState memory state)
|
||||||
|
private
|
||||||
|
returns (bytes memory returnResult)
|
||||||
|
{
|
||||||
|
LibNativeOrder.RfqOrder memory order;
|
||||||
|
LibSignature.Signature memory signature;
|
||||||
|
uint128 takerTokenFillAmount;
|
||||||
|
|
||||||
|
bytes memory args = _extractArgumentsFromCallData(state.mtx.callData);
|
||||||
|
(order, signature, takerTokenFillAmount) = abi.decode(args, (LibNativeOrder.RfqOrder, LibSignature.Signature, uint128));
|
||||||
|
|
||||||
|
return _callSelf(
|
||||||
|
state.hash,
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
INativeOrdersFeature._fillRfqOrder.selector,
|
||||||
|
order,
|
||||||
|
signature,
|
||||||
|
takerTokenFillAmount,
|
||||||
|
state.mtx.signer // taker is mtx signer
|
||||||
|
),
|
||||||
|
state.mtx.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Make an arbitrary internal, meta-transaction call.
|
/// @dev Make an arbitrary internal, meta-transaction call.
|
||||||
/// Warning: Do not let unadulterated `callData` into this function.
|
/// Warning: Do not let unadulterated `callData` into this function.
|
||||||
function _callSelf(bytes32 hash, bytes memory callData, uint256 value)
|
function _callSelf(bytes32 hash, bytes memory callData, uint256 value)
|
||||||
|
1024
contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol
Normal file
1024
contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol
Normal file
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,6 @@ contract SimpleFunctionRegistryFeature is
|
|||||||
// Register getters.
|
// Register getters.
|
||||||
_extend(this.getRollbackLength.selector, _implementation);
|
_extend(this.getRollbackLength.selector, _implementation);
|
||||||
_extend(this.getRollbackEntryAtIndex.selector, _implementation);
|
_extend(this.getRollbackEntryAtIndex.selector, _implementation);
|
||||||
_extend(this.getFunctionImplementation.selector, _implementation);
|
|
||||||
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
return LibBootstrap.BOOTSTRAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,18 +151,6 @@ contract SimpleFunctionRegistryFeature is
|
|||||||
return LibSimpleFunctionRegistryStorage.getStorage().implHistory[selector][idx];
|
return LibSimpleFunctionRegistryStorage.getStorage().implHistory[selector][idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Get the implementation contract of a registered function.
|
|
||||||
/// @param selector The function selector.
|
|
||||||
/// @return impl The implementation contract address.
|
|
||||||
function getFunctionImplementation(bytes4 selector)
|
|
||||||
external
|
|
||||||
override
|
|
||||||
view
|
|
||||||
returns (address impl)
|
|
||||||
{
|
|
||||||
return LibProxyStorage.getStorage().impls[selector];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @dev Register or replace a function.
|
/// @dev Register or replace a function.
|
||||||
/// @param selector The function selector.
|
/// @param selector The function selector.
|
||||||
/// @param impl The implementation contract for the function.
|
/// @param impl The implementation contract for the function.
|
||||||
|
@@ -25,24 +25,24 @@ import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
|||||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||||
import "../errors/LibTransformERC20RichErrors.sol";
|
import "../errors/LibTransformERC20RichErrors.sol";
|
||||||
import "../fixins/FixinCommon.sol";
|
import "../fixins/FixinCommon.sol";
|
||||||
|
import "../fixins/FixinTokenSpender.sol";
|
||||||
import "../migrations/LibMigrate.sol";
|
import "../migrations/LibMigrate.sol";
|
||||||
import "../external/IFlashWallet.sol";
|
import "../external/IFlashWallet.sol";
|
||||||
import "../external/FlashWallet.sol";
|
import "../external/FlashWallet.sol";
|
||||||
import "../storage/LibTransformERC20Storage.sol";
|
import "../storage/LibTransformERC20Storage.sol";
|
||||||
import "../transformers/IERC20Transformer.sol";
|
import "../transformers/IERC20Transformer.sol";
|
||||||
import "../transformers/LibERC20Transformer.sol";
|
import "../transformers/LibERC20Transformer.sol";
|
||||||
import "./libs/LibSignedCallData.sol";
|
|
||||||
import "./ITransformERC20Feature.sol";
|
import "./ITransformERC20Feature.sol";
|
||||||
import "./IFeature.sol";
|
import "./IFeature.sol";
|
||||||
import "./ISignatureValidatorFeature.sol";
|
import "./ISignatureValidatorFeature.sol";
|
||||||
import "./libs/LibTokenSpender.sol";
|
|
||||||
|
|
||||||
|
|
||||||
/// @dev Feature to composably transform between ERC20 tokens.
|
/// @dev Feature to composably transform between ERC20 tokens.
|
||||||
contract TransformERC20Feature is
|
contract TransformERC20Feature is
|
||||||
IFeature,
|
IFeature,
|
||||||
ITransformERC20Feature,
|
ITransformERC20Feature,
|
||||||
FixinCommon
|
FixinCommon,
|
||||||
|
FixinTokenSpender
|
||||||
{
|
{
|
||||||
using LibSafeMathV06 for uint256;
|
using LibSafeMathV06 for uint256;
|
||||||
using LibRichErrorsV06 for bytes;
|
using LibRichErrorsV06 for bytes;
|
||||||
@@ -58,7 +58,12 @@ contract TransformERC20Feature is
|
|||||||
/// @dev Name of this feature.
|
/// @dev Name of this feature.
|
||||||
string public constant override FEATURE_NAME = "TransformERC20";
|
string public constant override FEATURE_NAME = "TransformERC20";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 0);
|
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 1);
|
||||||
|
|
||||||
|
constructor(bytes32 greedyTokensBloomFilter)
|
||||||
|
public
|
||||||
|
FixinTokenSpender(greedyTokensBloomFilter)
|
||||||
|
{}
|
||||||
|
|
||||||
/// @dev Initialize and register this feature.
|
/// @dev Initialize and register this feature.
|
||||||
/// Should be delegatecalled by `Migrate.migrate()`.
|
/// Should be delegatecalled by `Migrate.migrate()`.
|
||||||
@@ -171,8 +176,6 @@ contract TransformERC20Feature is
|
|||||||
payable
|
payable
|
||||||
returns (uint256 outputTokenAmount)
|
returns (uint256 outputTokenAmount)
|
||||||
{
|
{
|
||||||
(bytes32 callDataHash, bytes memory callDataSignature) =
|
|
||||||
LibSignedCallData.parseCallData(msg.data);
|
|
||||||
return _transformERC20Private(
|
return _transformERC20Private(
|
||||||
TransformERC20Args({
|
TransformERC20Args({
|
||||||
taker: msg.sender,
|
taker: msg.sender,
|
||||||
@@ -180,9 +183,7 @@ contract TransformERC20Feature is
|
|||||||
outputToken: outputToken,
|
outputToken: outputToken,
|
||||||
inputTokenAmount: inputTokenAmount,
|
inputTokenAmount: inputTokenAmount,
|
||||||
minOutputTokenAmount: minOutputTokenAmount,
|
minOutputTokenAmount: minOutputTokenAmount,
|
||||||
transformations: transformations,
|
transformations: transformations
|
||||||
callDataHash: callDataHash,
|
|
||||||
callDataSignature: callDataSignature
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -208,13 +209,19 @@ contract TransformERC20Feature is
|
|||||||
private
|
private
|
||||||
returns (uint256 outputTokenAmount)
|
returns (uint256 outputTokenAmount)
|
||||||
{
|
{
|
||||||
// If the input token amount is -1, transform the taker's entire
|
// If the input token amount is -1 and we are not selling ETH,
|
||||||
// spendable balance.
|
// transform the taker's entire spendable balance.
|
||||||
if (args.inputTokenAmount == uint256(-1)) {
|
if (args.inputTokenAmount == uint256(-1)) {
|
||||||
args.inputTokenAmount = LibTokenSpender.getSpendableERC20BalanceOf(
|
if (LibERC20Transformer.isTokenETH(args.inputToken)) {
|
||||||
args.inputToken,
|
// We can't pull more ETH from the taker, so we just set the
|
||||||
args.taker
|
// input token amount to the value attached to the call.
|
||||||
);
|
args.inputTokenAmount = msg.value;
|
||||||
|
} else {
|
||||||
|
args.inputTokenAmount = _getSpendableERC20BalanceOf(
|
||||||
|
args.inputToken,
|
||||||
|
args.taker
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TransformERC20PrivateState memory state;
|
TransformERC20PrivateState memory state;
|
||||||
@@ -234,22 +241,13 @@ contract TransformERC20Feature is
|
|||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Validate that the calldata was signed by the quote signer.
|
|
||||||
// `validCallDataHash` will be 0x0 if not.
|
|
||||||
bytes32 validCallDataHash = _getValidCallDataHash(
|
|
||||||
args.callDataHash,
|
|
||||||
args.callDataSignature
|
|
||||||
);
|
|
||||||
// Perform transformations.
|
// Perform transformations.
|
||||||
for (uint256 i = 0; i < args.transformations.length; ++i) {
|
for (uint256 i = 0; i < args.transformations.length; ++i) {
|
||||||
_executeTransformation(
|
_executeTransformation(
|
||||||
state.wallet,
|
state.wallet,
|
||||||
args.transformations[i],
|
args.transformations[i],
|
||||||
state.transformerDeployer,
|
state.transformerDeployer,
|
||||||
args.taker,
|
args.taker
|
||||||
// Transformers will receive a null calldata hash if
|
|
||||||
// the calldata was not properly signed.
|
|
||||||
validCallDataHash
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,7 +315,12 @@ contract TransformERC20Feature is
|
|||||||
// Transfer input tokens.
|
// Transfer input tokens.
|
||||||
if (!LibERC20Transformer.isTokenETH(inputToken)) {
|
if (!LibERC20Transformer.isTokenETH(inputToken)) {
|
||||||
// Token is not ETH, so pull ERC20 tokens.
|
// Token is not ETH, so pull ERC20 tokens.
|
||||||
LibTokenSpender.spendERC20Tokens(inputToken, from, to, amount);
|
_transferERC20Tokens(
|
||||||
|
inputToken,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
amount
|
||||||
|
);
|
||||||
} else if (msg.value < amount) {
|
} else if (msg.value < amount) {
|
||||||
// Token is ETH, so the caller must attach enough ETH to the call.
|
// Token is ETH, so the caller must attach enough ETH to the call.
|
||||||
LibTransformERC20RichErrors.InsufficientEthAttachedError(
|
LibTransformERC20RichErrors.InsufficientEthAttachedError(
|
||||||
@@ -332,13 +335,11 @@ contract TransformERC20Feature is
|
|||||||
/// @param transformation The transformation.
|
/// @param transformation The transformation.
|
||||||
/// @param transformerDeployer The address of the transformer deployer.
|
/// @param transformerDeployer The address of the transformer deployer.
|
||||||
/// @param taker The taker address.
|
/// @param taker The taker address.
|
||||||
/// @param callDataHash Hash of the calldata.
|
|
||||||
function _executeTransformation(
|
function _executeTransformation(
|
||||||
IFlashWallet wallet,
|
IFlashWallet wallet,
|
||||||
Transformation memory transformation,
|
Transformation memory transformation,
|
||||||
address transformerDeployer,
|
address transformerDeployer,
|
||||||
address payable taker,
|
address payable taker
|
||||||
bytes32 callDataHash
|
|
||||||
)
|
)
|
||||||
private
|
private
|
||||||
{
|
{
|
||||||
@@ -355,7 +356,6 @@ contract TransformERC20Feature is
|
|||||||
abi.encodeWithSelector(
|
abi.encodeWithSelector(
|
||||||
IERC20Transformer.transform.selector,
|
IERC20Transformer.transform.selector,
|
||||||
IERC20Transformer.TransformContext({
|
IERC20Transformer.TransformContext({
|
||||||
callDataHash: callDataHash,
|
|
||||||
sender: msg.sender,
|
sender: msg.sender,
|
||||||
taker: taker,
|
taker: taker,
|
||||||
data: transformation.data
|
data: transformation.data
|
||||||
|
@@ -37,7 +37,9 @@ contract UniswapFeature is
|
|||||||
/// @dev Name of this feature.
|
/// @dev Name of this feature.
|
||||||
string public constant override FEATURE_NAME = "UniswapFeature";
|
string public constant override FEATURE_NAME = "UniswapFeature";
|
||||||
/// @dev Version of this feature.
|
/// @dev Version of this feature.
|
||||||
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
|
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 1);
|
||||||
|
/// @dev A bloom filter for tokens that consume all gas when `transferFrom()` fails.
|
||||||
|
bytes32 public immutable GREEDY_TOKENS_BLOOM_FILTER;
|
||||||
/// @dev WETH contract.
|
/// @dev WETH contract.
|
||||||
IEtherTokenV06 private immutable WETH;
|
IEtherTokenV06 private immutable WETH;
|
||||||
/// @dev AllowanceTarget instance.
|
/// @dev AllowanceTarget instance.
|
||||||
@@ -66,6 +68,8 @@ contract UniswapFeature is
|
|||||||
uint256 constant private UNISWAP_PAIR_SWAP_CALL_SELECTOR_32 = 0x022c0d9f00000000000000000000000000000000000000000000000000000000;
|
uint256 constant private UNISWAP_PAIR_SWAP_CALL_SELECTOR_32 = 0x022c0d9f00000000000000000000000000000000000000000000000000000000;
|
||||||
// bytes4(keccak256("transferFrom(address,address,uint256)"))
|
// bytes4(keccak256("transferFrom(address,address,uint256)"))
|
||||||
uint256 constant private TRANSFER_FROM_CALL_SELECTOR_32 = 0x23b872dd00000000000000000000000000000000000000000000000000000000;
|
uint256 constant private TRANSFER_FROM_CALL_SELECTOR_32 = 0x23b872dd00000000000000000000000000000000000000000000000000000000;
|
||||||
|
// bytes4(keccak256("allowance(address,address)"))
|
||||||
|
uint256 constant private ALLOWANCE_CALL_SELECTOR_32 = 0xdd62ed3e00000000000000000000000000000000000000000000000000000000;
|
||||||
// bytes4(keccak256("withdraw(uint256)"))
|
// bytes4(keccak256("withdraw(uint256)"))
|
||||||
uint256 constant private WETH_WITHDRAW_CALL_SELECTOR_32 = 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000;
|
uint256 constant private WETH_WITHDRAW_CALL_SELECTOR_32 = 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000;
|
||||||
// bytes4(keccak256("deposit()"))
|
// bytes4(keccak256("deposit()"))
|
||||||
@@ -76,9 +80,15 @@ contract UniswapFeature is
|
|||||||
/// @dev Construct this contract.
|
/// @dev Construct this contract.
|
||||||
/// @param weth The WETH contract.
|
/// @param weth The WETH contract.
|
||||||
/// @param allowanceTarget The AllowanceTarget contract.
|
/// @param allowanceTarget The AllowanceTarget contract.
|
||||||
constructor(IEtherTokenV06 weth, IAllowanceTarget allowanceTarget) public {
|
/// @param greedyTokensBloomFilter The bloom filter for greedy tokens.
|
||||||
|
constructor(
|
||||||
|
IEtherTokenV06 weth,
|
||||||
|
IAllowanceTarget allowanceTarget,
|
||||||
|
bytes32 greedyTokensBloomFilter
|
||||||
|
) public {
|
||||||
WETH = weth;
|
WETH = weth;
|
||||||
ALLOWANCE_TARGET = allowanceTarget;
|
ALLOWANCE_TARGET = allowanceTarget;
|
||||||
|
GREEDY_TOKENS_BLOOM_FILTER = greedyTokensBloomFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Initialize and register this feature.
|
/// @dev Initialize and register this feature.
|
||||||
@@ -114,6 +124,7 @@ contract UniswapFeature is
|
|||||||
// Load immutables onto the stack.
|
// Load immutables onto the stack.
|
||||||
IEtherTokenV06 weth = WETH;
|
IEtherTokenV06 weth = WETH;
|
||||||
IAllowanceTarget allowanceTarget = ALLOWANCE_TARGET;
|
IAllowanceTarget allowanceTarget = ALLOWANCE_TARGET;
|
||||||
|
bytes32 greedyTokensBloomFilter = GREEDY_TOKENS_BLOOM_FILTER;
|
||||||
|
|
||||||
// Store some vars in memory to get around stack limits.
|
// Store some vars in memory to get around stack limits.
|
||||||
assembly {
|
assembly {
|
||||||
@@ -125,6 +136,8 @@ contract UniswapFeature is
|
|||||||
mstore(0xA40, weth)
|
mstore(0xA40, weth)
|
||||||
// mload(0xA60) == ALLOWANCE_TARGET
|
// mload(0xA60) == ALLOWANCE_TARGET
|
||||||
mstore(0xA60, allowanceTarget)
|
mstore(0xA60, allowanceTarget)
|
||||||
|
// mload(0xA80) == GREEDY_TOKENS_BLOOM_FILTER
|
||||||
|
mstore(0xA80, greedyTokensBloomFilter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,53 +167,16 @@ contract UniswapFeature is
|
|||||||
}
|
}
|
||||||
|
|
||||||
if iszero(i) {
|
if iszero(i) {
|
||||||
|
// This is the first token in the path.
|
||||||
switch eq(sellToken, ETH_TOKEN_ADDRESS_32)
|
switch eq(sellToken, ETH_TOKEN_ADDRESS_32)
|
||||||
case 0 {
|
case 0 { // Not selling ETH. Selling an ERC20 instead.
|
||||||
|
// Make sure ETH was not attached to the call.
|
||||||
|
if gt(callvalue(), 0) {
|
||||||
|
revert(0, 0)
|
||||||
|
}
|
||||||
// For the first pair we need to transfer sellTokens into the
|
// For the first pair we need to transfer sellTokens into the
|
||||||
// pair contract.
|
// pair contract.
|
||||||
mstore(0xB00, TRANSFER_FROM_CALL_SELECTOR_32)
|
moveTakerTokensTo(sellToken, pair, sellAmount)
|
||||||
mstore(0xB04, caller())
|
|
||||||
mstore(0xB24, pair)
|
|
||||||
mstore(0xB44, sellAmount)
|
|
||||||
|
|
||||||
// Copy only the first 32 bytes of return data. We
|
|
||||||
// only care about reading a boolean in the success
|
|
||||||
// case, and we discard the return data in the
|
|
||||||
// failure case.
|
|
||||||
let success := call(gas(), sellToken, 0, 0xB00, 0x64, 0xC00, 0x20)
|
|
||||||
|
|
||||||
let rdsize := returndatasize()
|
|
||||||
|
|
||||||
// Check for ERC20 success. ERC20 tokens should
|
|
||||||
// return a boolean, but some return nothing or
|
|
||||||
// extra data. We accept 0-length return data as
|
|
||||||
// success, or at least 32 bytes that starts with
|
|
||||||
// a 32-byte boolean true.
|
|
||||||
success := and(
|
|
||||||
success, // call itself succeeded
|
|
||||||
or(
|
|
||||||
iszero(rdsize), // no return data, or
|
|
||||||
and(
|
|
||||||
iszero(lt(rdsize, 32)), // at least 32 bytes
|
|
||||||
eq(mload(0xC00), 1) // starts with uint256(1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if iszero(success) {
|
|
||||||
// Try to fall back to the allowance target.
|
|
||||||
mstore(0xB00, ALLOWANCE_TARGET_EXECUTE_CALL_SELECTOR_32)
|
|
||||||
mstore(0xB04, sellToken)
|
|
||||||
mstore(0xB24, 0x40)
|
|
||||||
mstore(0xB44, 0x64)
|
|
||||||
mstore(0xB64, TRANSFER_FROM_CALL_SELECTOR_32)
|
|
||||||
mstore(0xB68, caller())
|
|
||||||
mstore(0xB88, pair)
|
|
||||||
mstore(0xBA8, sellAmount)
|
|
||||||
if iszero(call(gas(), mload(0xA60), 0, 0xB00, 0xC8, 0x00, 0x0)) {
|
|
||||||
bubbleRevert()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
// If selling ETH, we need to wrap it to WETH and transfer to the
|
// If selling ETH, we need to wrap it to WETH and transfer to the
|
||||||
@@ -232,6 +208,10 @@ contract UniswapFeature is
|
|||||||
if iszero(staticcall(gas(), pair, 0xB00, 0x4, 0xC00, 0x40)) {
|
if iszero(staticcall(gas(), pair, 0xB00, 0x4, 0xC00, 0x40)) {
|
||||||
bubbleRevert()
|
bubbleRevert()
|
||||||
}
|
}
|
||||||
|
// Revert if the pair contract does not return two words.
|
||||||
|
if iszero(eq(returndatasize(), 0x40)) {
|
||||||
|
revert(0,0)
|
||||||
|
}
|
||||||
|
|
||||||
// Sell amount for this hop is the previous buy amount.
|
// Sell amount for this hop is the previous buy amount.
|
||||||
let pairSellAmount := buyAmount
|
let pairSellAmount := buyAmount
|
||||||
@@ -389,6 +369,110 @@ contract UniswapFeature is
|
|||||||
returndatacopy(0, 0, returndatasize())
|
returndatacopy(0, 0, returndatasize())
|
||||||
revert(0, returndatasize())
|
revert(0, returndatasize())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move `amount` tokens from the taker/caller to `to`.
|
||||||
|
function moveTakerTokensTo(token, to, amount) {
|
||||||
|
|
||||||
|
// If the token is possibly greedy, we check the allowance rather
|
||||||
|
// than relying on letting the transferFrom() call fail and
|
||||||
|
// falling through to legacy allowance target because the token
|
||||||
|
// will eat all our gas.
|
||||||
|
if isTokenPossiblyGreedy(token) {
|
||||||
|
// Check if we have enough direct allowance by calling
|
||||||
|
// `token.allowance()``
|
||||||
|
mstore(0xB00, ALLOWANCE_CALL_SELECTOR_32)
|
||||||
|
mstore(0xB04, caller())
|
||||||
|
mstore(0xB24, address())
|
||||||
|
let success := staticcall(gas(), token, 0xB00, 0x44, 0xC00, 0x20)
|
||||||
|
if iszero(success) {
|
||||||
|
// Call to allowance() failed.
|
||||||
|
bubbleRevert()
|
||||||
|
}
|
||||||
|
// Make sure the allowance call returned a single word.
|
||||||
|
if iszero(eq(returndatasize(), 0x20)) {
|
||||||
|
revert(0, 0)
|
||||||
|
}
|
||||||
|
// Call succeeded.
|
||||||
|
// Result is stored in 0xC00-0xC20.
|
||||||
|
if lt(mload(0xC00), amount) {
|
||||||
|
// We don't have enough direct allowance, so try
|
||||||
|
// going through the legacy allowance taregt.
|
||||||
|
moveTakerTokensToWithLegacyAllowanceTarget(token, to, amount)
|
||||||
|
leave
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we will optimistically try to perform a `transferFrom()`
|
||||||
|
// directly then if it fails we will go through the legacy allowance target.
|
||||||
|
mstore(0xB00, TRANSFER_FROM_CALL_SELECTOR_32)
|
||||||
|
mstore(0xB04, caller())
|
||||||
|
mstore(0xB24, to)
|
||||||
|
mstore(0xB44, amount)
|
||||||
|
|
||||||
|
let success := call(
|
||||||
|
gas(),
|
||||||
|
token,
|
||||||
|
0,
|
||||||
|
0xB00,
|
||||||
|
0x64,
|
||||||
|
0xC00,
|
||||||
|
// Copy only the first 32 bytes of return data. We
|
||||||
|
// only care about reading a boolean in the success
|
||||||
|
// case, and we discard the return data in the
|
||||||
|
// failure case.
|
||||||
|
0x20
|
||||||
|
)
|
||||||
|
|
||||||
|
let rdsize := returndatasize()
|
||||||
|
|
||||||
|
// Check for ERC20 success. ERC20 tokens should
|
||||||
|
// return a boolean, but some return nothing or
|
||||||
|
// extra data. We accept 0-length return data as
|
||||||
|
// success, or at least 32 bytes that starts with
|
||||||
|
// a 32-byte boolean true.
|
||||||
|
success := and(
|
||||||
|
success, // call itself succeeded
|
||||||
|
or(
|
||||||
|
iszero(rdsize), // no return data, or
|
||||||
|
and(
|
||||||
|
iszero(lt(rdsize, 32)), // at least 32 bytes
|
||||||
|
eq(mload(0xC00), 1) // starts with uint256(1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if iszero(success) {
|
||||||
|
// Try to fall back to the allowance target.
|
||||||
|
moveTakerTokensToWithLegacyAllowanceTarget(token, to, amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move tokens by going through the legacy allowance target contract.
|
||||||
|
function moveTakerTokensToWithLegacyAllowanceTarget(token, to, amount) {
|
||||||
|
mstore(0xB00, ALLOWANCE_TARGET_EXECUTE_CALL_SELECTOR_32)
|
||||||
|
mstore(0xB04, token)
|
||||||
|
mstore(0xB24, 0x40)
|
||||||
|
mstore(0xB44, 0x64)
|
||||||
|
mstore(0xB64, TRANSFER_FROM_CALL_SELECTOR_32)
|
||||||
|
mstore(0xB68, caller())
|
||||||
|
mstore(0xB88, to)
|
||||||
|
mstore(0xBA8, amount)
|
||||||
|
if iszero(call(gas(), mload(0xA60), 0, 0xB00, 0xC8, 0x00, 0x0)) {
|
||||||
|
bubbleRevert()
|
||||||
|
}
|
||||||
|
// If this fall back failed, the swap will most likely fail
|
||||||
|
// so there's no need to validate the result.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if a token possibly belongs to the GREEDY_TOKENS_BLOOM_FILTER
|
||||||
|
// bloom filter.
|
||||||
|
function isTokenPossiblyGreedy(token) -> isPossiblyGreedy {
|
||||||
|
// The hash is given by:
|
||||||
|
// (1 << (keccak256(token) % 256)) | (1 << (token % 256))
|
||||||
|
mstore(0, token)
|
||||||
|
let h := or(shl(mod(keccak256(0, 32), 256), 1), shl(mod(token, 256), 1))
|
||||||
|
isPossiblyGreedy := eq(and(h, mload(0xA80)), h)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revert if we bought too little.
|
// Revert if we bought too little.
|
||||||
|
218
contracts/zero-ex/contracts/src/features/libs/LibNativeOrder.sol
Normal file
218
contracts/zero-ex/contracts/src/features/libs/LibNativeOrder.sol
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev A library for common native order operations.
|
||||||
|
library LibNativeOrder {
|
||||||
|
|
||||||
|
enum OrderStatus {
|
||||||
|
INVALID,
|
||||||
|
FILLABLE,
|
||||||
|
FILLED,
|
||||||
|
CANCELLED,
|
||||||
|
EXPIRED
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev A standard OTC or OO limit order.
|
||||||
|
struct LimitOrder {
|
||||||
|
IERC20TokenV06 makerToken;
|
||||||
|
IERC20TokenV06 takerToken;
|
||||||
|
uint128 makerAmount;
|
||||||
|
uint128 takerAmount;
|
||||||
|
uint128 takerTokenFeeAmount;
|
||||||
|
address maker;
|
||||||
|
address taker;
|
||||||
|
address sender;
|
||||||
|
address feeRecipient;
|
||||||
|
bytes32 pool;
|
||||||
|
uint64 expiry;
|
||||||
|
uint256 salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev An RFQ limit order.
|
||||||
|
struct RfqOrder {
|
||||||
|
IERC20TokenV06 makerToken;
|
||||||
|
IERC20TokenV06 takerToken;
|
||||||
|
uint128 makerAmount;
|
||||||
|
uint128 takerAmount;
|
||||||
|
address maker;
|
||||||
|
address taker;
|
||||||
|
address txOrigin;
|
||||||
|
bytes32 pool;
|
||||||
|
uint64 expiry;
|
||||||
|
uint256 salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Info on a limit or RFQ order.
|
||||||
|
struct OrderInfo {
|
||||||
|
bytes32 orderHash;
|
||||||
|
OrderStatus status;
|
||||||
|
uint128 takerTokenFilledAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 private constant UINT_128_MASK = (1 << 128) - 1;
|
||||||
|
uint256 private constant UINT_64_MASK = (1 << 64) - 1;
|
||||||
|
uint256 private constant ADDRESS_MASK = (1 << 160) - 1;
|
||||||
|
|
||||||
|
// The type hash for limit orders, which is:
|
||||||
|
// keccak256(abi.encodePacked(
|
||||||
|
// "LimitOrder(",
|
||||||
|
// "address makerToken,",
|
||||||
|
// "address takerToken,",
|
||||||
|
// "uint128 makerAmount,",
|
||||||
|
// "uint128 takerAmount,",
|
||||||
|
// "uint128 takerTokenFeeAmount,",
|
||||||
|
// "address maker,",
|
||||||
|
// "address taker,",
|
||||||
|
// "address sender,",
|
||||||
|
// "address feeRecipient,",
|
||||||
|
// "bytes32 pool,",
|
||||||
|
// "uint64 expiry,",
|
||||||
|
// "uint256 salt"
|
||||||
|
// ")"
|
||||||
|
// ))
|
||||||
|
uint256 private constant _LIMIT_ORDER_TYPEHASH =
|
||||||
|
0xce918627cb55462ddbb85e73de69a8b322f2bc88f4507c52fcad6d4c33c29d49;
|
||||||
|
|
||||||
|
// The type hash for RFQ orders, which is:
|
||||||
|
// keccak256(abi.encodePacked(
|
||||||
|
// "RfqOrder(",
|
||||||
|
// "address makerToken,",
|
||||||
|
// "address takerToken,",
|
||||||
|
// "uint128 makerAmount,",
|
||||||
|
// "uint128 takerAmount,",
|
||||||
|
// "address maker,",
|
||||||
|
// "address txOrigin,",
|
||||||
|
// "address taker,",
|
||||||
|
// "bytes32 pool,",
|
||||||
|
// "uint64 expiry,",
|
||||||
|
// "uint256 salt"
|
||||||
|
// ")"
|
||||||
|
// ))
|
||||||
|
uint256 private constant _RFQ_ORDER_TYPEHASH =
|
||||||
|
0xe593d3fdfa8b60e5e17a1b2204662ecbe15c23f2084b9ad5bae40359540a7da9;
|
||||||
|
|
||||||
|
/// @dev Get the struct hash of a limit order.
|
||||||
|
/// @param order The limit order.
|
||||||
|
/// @return structHash The struct hash of the order.
|
||||||
|
function getLimitOrderStructHash(LimitOrder memory order)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes32 structHash)
|
||||||
|
{
|
||||||
|
// The struct hash is:
|
||||||
|
// keccak256(abi.encode(
|
||||||
|
// TYPE_HASH,
|
||||||
|
// order.makerToken,
|
||||||
|
// order.takerToken,
|
||||||
|
// order.makerAmount,
|
||||||
|
// order.takerAmount,
|
||||||
|
// order.takerTokenFeeAmount,
|
||||||
|
// order.maker,
|
||||||
|
// order.taker,
|
||||||
|
// order.sender,
|
||||||
|
// order.feeRecipient,
|
||||||
|
// order.pool,
|
||||||
|
// order.expiry,
|
||||||
|
// order.salt,
|
||||||
|
// ))
|
||||||
|
assembly {
|
||||||
|
let mem := mload(0x40)
|
||||||
|
mstore(mem, _LIMIT_ORDER_TYPEHASH)
|
||||||
|
// order.makerToken;
|
||||||
|
mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order)))
|
||||||
|
// order.takerToken;
|
||||||
|
mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20))))
|
||||||
|
// order.makerAmount;
|
||||||
|
mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40))))
|
||||||
|
// order.takerAmount;
|
||||||
|
mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
|
||||||
|
// order.takerTokenFeeAmount;
|
||||||
|
mstore(add(mem, 0xA0), and(UINT_128_MASK, mload(add(order, 0x80))))
|
||||||
|
// order.maker;
|
||||||
|
mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
|
||||||
|
// order.taker;
|
||||||
|
mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
|
||||||
|
// order.sender;
|
||||||
|
mstore(add(mem, 0x100), and(ADDRESS_MASK, mload(add(order, 0xE0))))
|
||||||
|
// order.feeRecipient;
|
||||||
|
mstore(add(mem, 0x120), and(ADDRESS_MASK, mload(add(order, 0x100))))
|
||||||
|
// order.pool;
|
||||||
|
mstore(add(mem, 0x140), mload(add(order, 0x120)))
|
||||||
|
// order.expiry;
|
||||||
|
mstore(add(mem, 0x160), and(UINT_64_MASK, mload(add(order, 0x140))))
|
||||||
|
// order.salt;
|
||||||
|
mstore(add(mem, 0x180), mload(add(order, 0x160)))
|
||||||
|
structHash := keccak256(mem, 0x1A0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Get the struct hash of a RFQ order.
|
||||||
|
/// @param order The RFQ order.
|
||||||
|
/// @return structHash The struct hash of the order.
|
||||||
|
function getRfqOrderStructHash(RfqOrder memory order)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (bytes32 structHash)
|
||||||
|
{
|
||||||
|
// The struct hash is:
|
||||||
|
// keccak256(abi.encode(
|
||||||
|
// TYPE_HASH,
|
||||||
|
// order.makerToken,
|
||||||
|
// order.takerToken,
|
||||||
|
// order.makerAmount,
|
||||||
|
// order.takerAmount,
|
||||||
|
// order.maker,
|
||||||
|
// order.taker,
|
||||||
|
// order.txOrigin,
|
||||||
|
// order.pool,
|
||||||
|
// order.expiry,
|
||||||
|
// order.salt,
|
||||||
|
// ))
|
||||||
|
assembly {
|
||||||
|
let mem := mload(0x40)
|
||||||
|
mstore(mem, _RFQ_ORDER_TYPEHASH)
|
||||||
|
// order.makerToken;
|
||||||
|
mstore(add(mem, 0x20), and(ADDRESS_MASK, mload(order)))
|
||||||
|
// order.takerToken;
|
||||||
|
mstore(add(mem, 0x40), and(ADDRESS_MASK, mload(add(order, 0x20))))
|
||||||
|
// order.makerAmount;
|
||||||
|
mstore(add(mem, 0x60), and(UINT_128_MASK, mload(add(order, 0x40))))
|
||||||
|
// order.takerAmount;
|
||||||
|
mstore(add(mem, 0x80), and(UINT_128_MASK, mload(add(order, 0x60))))
|
||||||
|
// order.maker;
|
||||||
|
mstore(add(mem, 0xA0), and(ADDRESS_MASK, mload(add(order, 0x80))))
|
||||||
|
// order.taker;
|
||||||
|
mstore(add(mem, 0xC0), and(ADDRESS_MASK, mload(add(order, 0xA0))))
|
||||||
|
// order.txOrigin;
|
||||||
|
mstore(add(mem, 0xE0), and(ADDRESS_MASK, mload(add(order, 0xC0))))
|
||||||
|
// order.pool;
|
||||||
|
mstore(add(mem, 0x100), mload(add(order, 0xE0)))
|
||||||
|
// order.expiry;
|
||||||
|
mstore(add(mem, 0x120), and(UINT_64_MASK, mload(add(order, 0x100))))
|
||||||
|
// order.salt;
|
||||||
|
mstore(add(mem, 0x140), mload(add(order, 0x120)))
|
||||||
|
structHash := keccak256(mem, 0x160)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -38,7 +38,7 @@ library LibSignature {
|
|||||||
/// The valid range is given by fig (283) of the yellow paper.
|
/// The valid range is given by fig (283) of the yellow paper.
|
||||||
uint256 private constant ECDSA_SIGNATURE_S_LIMIT = ECDSA_SIGNATURE_R_LIMIT / 2 + 1;
|
uint256 private constant ECDSA_SIGNATURE_S_LIMIT = ECDSA_SIGNATURE_R_LIMIT / 2 + 1;
|
||||||
|
|
||||||
/// @dev Allowed signature types.
|
/// @dev Allowed signature types.
|
||||||
enum SignatureType {
|
enum SignatureType {
|
||||||
ILLEGAL,
|
ILLEGAL,
|
||||||
INVALID,
|
INVALID,
|
||||||
|
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright 2020 ZeroEx Intl.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pragma solidity ^0.6.5;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
|
||||||
|
|
||||||
|
|
||||||
/// @dev Library for working with signed calldata.
|
|
||||||
library LibSignedCallData {
|
|
||||||
using LibBytesV06 for bytes;
|
|
||||||
|
|
||||||
// bytes4(keccak256('SignedCallDataSignature(bytes)'))
|
|
||||||
bytes4 constant private SIGNATURE_SELECTOR = 0xf86d1d92;
|
|
||||||
|
|
||||||
/// @dev Try to parse potentially signed calldata into its hash and signature
|
|
||||||
/// components. Signed calldata has signature data appended to it.
|
|
||||||
/// @param callData the raw call data.
|
|
||||||
/// @return callDataHash If a signature is detected, this will be the hash of
|
|
||||||
/// the bytes preceding the signature data. Otherwise, this
|
|
||||||
/// will be the hash of the entire `callData`.
|
|
||||||
/// @return signature The signature bytes, if present.
|
|
||||||
function parseCallData(bytes memory callData)
|
|
||||||
internal
|
|
||||||
pure
|
|
||||||
returns (bytes32 callDataHash, bytes memory signature)
|
|
||||||
{
|
|
||||||
// Signed calldata has a 70 byte signature appended as:
|
|
||||||
// ```
|
|
||||||
// abi.encodePacked(
|
|
||||||
// callData,
|
|
||||||
// bytes4(keccak256('SignedCallDataSignature(bytes)')),
|
|
||||||
// signature // 66 bytes
|
|
||||||
// );
|
|
||||||
// ```
|
|
||||||
|
|
||||||
// Try to detect an appended signature. This isn't foolproof, but an
|
|
||||||
// accidental false positive should highly unlikely. Additinally, the
|
|
||||||
// signature would also have to pass verification, so the risk here is
|
|
||||||
// low.
|
|
||||||
if (
|
|
||||||
// Signed callData has to be at least 70 bytes long.
|
|
||||||
callData.length < 70 ||
|
|
||||||
// The bytes4 at offset -70 should equal `SIGNATURE_SELECTOR`.
|
|
||||||
SIGNATURE_SELECTOR != callData.readBytes4(callData.length - 70)
|
|
||||||
) {
|
|
||||||
return (keccak256(callData), signature);
|
|
||||||
}
|
|
||||||
// Consider everything before the signature selector as the original
|
|
||||||
// calldata and everything after as the signature.
|
|
||||||
assembly {
|
|
||||||
callDataHash := keccak256(add(callData, 32), sub(mload(callData), 70))
|
|
||||||
}
|
|
||||||
signature = callData.slice(callData.length - 66, callData.length);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -21,72 +21,74 @@ pragma experimental ABIEncoderV2;
|
|||||||
|
|
||||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||||
import "../external/FeeCollector.sol";
|
import "../external/FeeCollector.sol";
|
||||||
import "../features/libs/LibTokenSpender.sol";
|
import "../external/FeeCollectorController.sol";
|
||||||
|
import "../external/LibFeeCollector.sol";
|
||||||
|
import "../vendor/v3/IStaking.sol";
|
||||||
|
|
||||||
|
|
||||||
/// @dev Helpers for collecting protocol fees.
|
/// @dev Helpers for collecting protocol fees.
|
||||||
abstract contract FixinProtocolFees {
|
abstract contract FixinProtocolFees {
|
||||||
bytes32 immutable feeCollectorCodeHash;
|
|
||||||
|
|
||||||
constructor() internal {
|
/// @dev The protocol fee multiplier.
|
||||||
feeCollectorCodeHash = keccak256(type(FeeCollector).creationCode);
|
uint32 public immutable PROTOCOL_FEE_MULTIPLIER;
|
||||||
}
|
/// @dev The `FeeCollectorController` contract.
|
||||||
|
FeeCollectorController private immutable FEE_COLLECTOR_CONTROLLER;
|
||||||
|
/// @dev Hash of the fee collector init code.
|
||||||
|
bytes32 private immutable FEE_COLLECTOR_INIT_CODE_HASH;
|
||||||
|
/// @dev The WETH token contract.
|
||||||
|
IEtherTokenV06 private immutable WETH;
|
||||||
|
/// @dev The staking contract.
|
||||||
|
IStaking private immutable STAKING;
|
||||||
|
|
||||||
/// @dev Collect the specified protocol fee in either WETH or ETH. If
|
constructor(
|
||||||
/// msg.value is non-zero, the fee will be paid in ETH. Otherwise,
|
IEtherTokenV06 weth,
|
||||||
/// this function attempts to transfer the fee in WETH. Either way,
|
IStaking staking,
|
||||||
/// The fee is stored in a per-pool fee collector contract.
|
FeeCollectorController feeCollectorController,
|
||||||
/// @param poolId The pool ID for which a fee is being collected.
|
uint32 protocolFeeMultiplier
|
||||||
/// @param amount The amount of ETH/WETH to be collected.
|
|
||||||
/// @param weth The WETH token contract.
|
|
||||||
function _collectProtocolFee(
|
|
||||||
bytes32 poolId,
|
|
||||||
uint256 amount,
|
|
||||||
IERC20TokenV06 weth
|
|
||||||
)
|
)
|
||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
FeeCollector feeCollector = _getFeeCollector(poolId);
|
FEE_COLLECTOR_CONTROLLER = feeCollectorController;
|
||||||
|
FEE_COLLECTOR_INIT_CODE_HASH =
|
||||||
|
feeCollectorController.FEE_COLLECTOR_INIT_CODE_HASH();
|
||||||
|
WETH = weth;
|
||||||
|
STAKING = staking;
|
||||||
|
PROTOCOL_FEE_MULTIPLIER = protocolFeeMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.value == 0) {
|
/// @dev Collect the specified protocol fee in ETH.
|
||||||
// WETH
|
/// The fee is stored in a per-pool fee collector contract.
|
||||||
LibTokenSpender.spendERC20Tokens(weth, msg.sender, address(feeCollector), amount);
|
/// @param poolId The pool ID for which a fee is being collected.
|
||||||
} else {
|
/// @return ethProtocolFeePaid How much protocol fee was collected in ETH.
|
||||||
// ETH
|
function _collectProtocolFee(bytes32 poolId)
|
||||||
(bool success,) = address(feeCollector).call{value: amount}("");
|
internal
|
||||||
require(success, "FixinProtocolFees/ETHER_TRANSFER_FALIED");
|
returns (uint256 ethProtocolFeePaid)
|
||||||
|
{
|
||||||
|
uint256 protocolFeePaid = _getSingleProtocolFee();
|
||||||
|
if (protocolFeePaid == 0) {
|
||||||
|
// Nothing to do.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
FeeCollector feeCollector = _getFeeCollector(poolId);
|
||||||
|
(bool success,) = address(feeCollector).call{value: protocolFeePaid}("");
|
||||||
|
require(success, "FixinProtocolFees/ETHER_TRANSFER_FALIED");
|
||||||
|
return protocolFeePaid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Transfer fees for a given pool to the staking contract.
|
/// @dev Transfer fees for a given pool to the staking contract.
|
||||||
/// @param poolId Identifies the pool whose fees are being paid.
|
/// @param poolId Identifies the pool whose fees are being paid.
|
||||||
function _transferFeesForPool(
|
function _transferFeesForPool(bytes32 poolId)
|
||||||
bytes32 poolId,
|
|
||||||
IStaking staking,
|
|
||||||
IEtherTokenV06 weth
|
|
||||||
)
|
|
||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
FeeCollector feeCollector = _getFeeCollector(poolId);
|
// This will create a FeeCollector contract (if necessary) and wrap
|
||||||
|
// fees for the pool ID.
|
||||||
uint256 codeSize;
|
FeeCollector feeCollector =
|
||||||
assembly {
|
FEE_COLLECTOR_CONTROLLER.prepareFeeCollectorToPayFees(poolId);
|
||||||
codeSize := extcodesize(feeCollector)
|
// All fees in the fee collector should be in WETH now.
|
||||||
}
|
uint256 bal = WETH.balanceOf(address(feeCollector));
|
||||||
|
|
||||||
if (codeSize == 0) {
|
|
||||||
// Create and initialize the contract if necessary.
|
|
||||||
new FeeCollector{salt: poolId}();
|
|
||||||
feeCollector.initialize(weth, staking, poolId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address(feeCollector).balance > 1) {
|
|
||||||
feeCollector.convertToWeth(weth);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint256 bal = weth.balanceOf(address(feeCollector));
|
|
||||||
if (bal > 1) {
|
if (bal > 1) {
|
||||||
// Leave 1 wei behind to avoid high SSTORE cost of zero-->non-zero.
|
// Leave 1 wei behind to avoid high SSTORE cost of zero-->non-zero.
|
||||||
staking.payProtocolFee(
|
STAKING.payProtocolFee(
|
||||||
address(feeCollector),
|
address(feeCollector),
|
||||||
address(feeCollector),
|
address(feeCollector),
|
||||||
bal - 1);
|
bal - 1);
|
||||||
@@ -95,20 +97,25 @@ abstract contract FixinProtocolFees {
|
|||||||
|
|
||||||
/// @dev Compute the CREATE2 address for a fee collector.
|
/// @dev Compute the CREATE2 address for a fee collector.
|
||||||
/// @param poolId The fee collector's pool ID.
|
/// @param poolId The fee collector's pool ID.
|
||||||
function _getFeeCollector(
|
function _getFeeCollector(bytes32 poolId)
|
||||||
bytes32 poolId
|
|
||||||
)
|
|
||||||
internal
|
internal
|
||||||
view
|
view
|
||||||
returns (FeeCollector)
|
returns (FeeCollector)
|
||||||
{
|
{
|
||||||
// Compute the CREATE2 address for the fee collector.
|
return FeeCollector(LibFeeCollector.getFeeCollectorAddress(
|
||||||
address payable addr = address(uint256(keccak256(abi.encodePacked(
|
address(FEE_COLLECTOR_CONTROLLER),
|
||||||
byte(0xff),
|
FEE_COLLECTOR_INIT_CODE_HASH,
|
||||||
address(this),
|
poolId
|
||||||
poolId, // pool ID is salt
|
));
|
||||||
feeCollectorCodeHash
|
}
|
||||||
))));
|
|
||||||
return FeeCollector(addr);
|
/// @dev Get the cost of a single protocol fee.
|
||||||
|
/// @return protocolFeeAmount The protocol fee amount, in ETH/WETH.
|
||||||
|
function _getSingleProtocolFee()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (uint256 protocolFeeAmount)
|
||||||
|
{
|
||||||
|
return uint256(PROTOCOL_FEE_MULTIPLIER) * tx.gasprice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,23 +19,37 @@
|
|||||||
pragma solidity ^0.6.5;
|
pragma solidity ^0.6.5;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||||
import "../../errors/LibSpenderRichErrors.sol";
|
import "../features/ITokenSpenderFeature.sol";
|
||||||
import "../ITokenSpenderFeature.sol";
|
import "../errors/LibSpenderRichErrors.sol";
|
||||||
|
import "../external/FeeCollector.sol";
|
||||||
|
import "../vendor/v3/IStaking.sol";
|
||||||
|
import "../vendor/v3/IStaking.sol";
|
||||||
|
|
||||||
library LibTokenSpender {
|
|
||||||
|
/// @dev Helpers for moving tokens around.
|
||||||
|
abstract contract FixinTokenSpender {
|
||||||
using LibRichErrorsV06 for bytes;
|
using LibRichErrorsV06 for bytes;
|
||||||
|
|
||||||
// Mask of the lower 20 bytes of a bytes32.
|
// Mask of the lower 20 bytes of a bytes32.
|
||||||
uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
|
uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
|
||||||
|
/// @dev A bloom filter for tokens that consume all gas when `transferFrom()` fails.
|
||||||
|
bytes32 public immutable GREEDY_TOKENS_BLOOM_FILTER;
|
||||||
|
|
||||||
|
/// @param greedyTokensBloomFilter The bloom filter for all greedy tokens.
|
||||||
|
constructor(bytes32 greedyTokensBloomFilter)
|
||||||
|
internal
|
||||||
|
{
|
||||||
|
GREEDY_TOKENS_BLOOM_FILTER = greedyTokensBloomFilter;
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Transfers ERC20 tokens from `owner` to `to`.
|
/// @dev Transfers ERC20 tokens from `owner` to `to`.
|
||||||
/// @param token The token to spend.
|
/// @param token The token to spend.
|
||||||
/// @param owner The owner of the tokens.
|
/// @param owner The owner of the tokens.
|
||||||
/// @param to The recipient of the tokens.
|
/// @param to The recipient of the tokens.
|
||||||
/// @param amount The amount of `token` to transfer.
|
/// @param amount The amount of `token` to transfer.
|
||||||
function spendERC20Tokens(
|
function _transferERC20Tokens(
|
||||||
IERC20TokenV06 token,
|
IERC20TokenV06 token,
|
||||||
address owner,
|
address owner,
|
||||||
address to,
|
address to,
|
||||||
@@ -46,7 +60,25 @@ library LibTokenSpender {
|
|||||||
bool success;
|
bool success;
|
||||||
bytes memory revertData;
|
bytes memory revertData;
|
||||||
|
|
||||||
require(address(token) != address(this), "LibTokenSpender/CANNOT_INVOKE_SELF");
|
require(address(token) != address(this), "FixinTokenSpender/CANNOT_INVOKE_SELF");
|
||||||
|
|
||||||
|
// If the token eats all gas when failing, we do not want to perform
|
||||||
|
// optimistic fall through to the old AllowanceTarget contract if the
|
||||||
|
// direct transferFrom() fails.
|
||||||
|
if (_isTokenPossiblyGreedy(token)) {
|
||||||
|
// If the token does not have a direct allowance on us then we use
|
||||||
|
// the allowance target.
|
||||||
|
if (token.allowance(owner, address(this)) < amount) {
|
||||||
|
_transferFromLegacyAllowanceTarget(
|
||||||
|
token,
|
||||||
|
owner,
|
||||||
|
to,
|
||||||
|
amount,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assembly {
|
assembly {
|
||||||
let ptr := mload(0x40) // free memory pointer
|
let ptr := mload(0x40) // free memory pointer
|
||||||
@@ -57,7 +89,15 @@ library LibTokenSpender {
|
|||||||
mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
|
mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
|
||||||
mstore(add(ptr, 0x44), amount)
|
mstore(add(ptr, 0x44), amount)
|
||||||
|
|
||||||
success := call(gas(), and(token, ADDRESS_MASK), 0, ptr, 0x64, 0, 0)
|
success := call(
|
||||||
|
gas(),
|
||||||
|
and(token, ADDRESS_MASK),
|
||||||
|
0,
|
||||||
|
ptr,
|
||||||
|
0x64,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
let rdsize := returndatasize()
|
let rdsize := returndatasize()
|
||||||
|
|
||||||
@@ -88,25 +128,13 @@ library LibTokenSpender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// Try the old AllowanceTarget.
|
_transferFromLegacyAllowanceTarget(
|
||||||
try ITokenSpenderFeature(address(this))._spendERC20Tokens(
|
token,
|
||||||
token,
|
owner,
|
||||||
owner,
|
to,
|
||||||
to,
|
amount,
|
||||||
amount
|
revertData
|
||||||
) {
|
);
|
||||||
} catch {
|
|
||||||
// Bubble up the first error message. (In general, the fallback to the
|
|
||||||
// allowance target is opportunistic. We ignore the specific error
|
|
||||||
// message if it fails.)
|
|
||||||
LibSpenderRichErrors.SpenderERC20TransferFromFailedError(
|
|
||||||
address(token),
|
|
||||||
owner,
|
|
||||||
to,
|
|
||||||
amount,
|
|
||||||
revertData
|
|
||||||
).rrevert();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +143,7 @@ library LibTokenSpender {
|
|||||||
/// @param token The token to spend.
|
/// @param token The token to spend.
|
||||||
/// @param owner The owner of the tokens.
|
/// @param owner The owner of the tokens.
|
||||||
/// @return amount The amount of tokens that can be pulled.
|
/// @return amount The amount of tokens that can be pulled.
|
||||||
function getSpendableERC20BalanceOf(
|
function _getSpendableERC20BalanceOf(
|
||||||
IERC20TokenV06 token,
|
IERC20TokenV06 token,
|
||||||
address owner
|
address owner
|
||||||
)
|
)
|
||||||
@@ -128,4 +156,53 @@ library LibTokenSpender {
|
|||||||
token.balanceOf(owner)
|
token.balanceOf(owner)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @dev Check if a token possibly belongs to the `GREEDY_TOKENS_BLOOM_FILTER`
|
||||||
|
/// bloom filter.
|
||||||
|
function _isTokenPossiblyGreedy(IERC20TokenV06 token)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (bool isPossiblyGreedy)
|
||||||
|
{
|
||||||
|
// The hash is given by:
|
||||||
|
// (1 << (keccak256(token) % 256)) | (1 << (token % 256))
|
||||||
|
bytes32 h;
|
||||||
|
assembly {
|
||||||
|
mstore(0, token)
|
||||||
|
h := or(shl(mod(keccak256(0, 32), 256), 1), shl(mod(token, 256), 1))
|
||||||
|
}
|
||||||
|
return (h & GREEDY_TOKENS_BLOOM_FILTER) == h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Transfer tokens using the legacy allowance target instead of
|
||||||
|
/// allowances directly set on the exchange proxy.
|
||||||
|
function _transferFromLegacyAllowanceTarget(
|
||||||
|
IERC20TokenV06 token,
|
||||||
|
address owner,
|
||||||
|
address to,
|
||||||
|
uint256 amount,
|
||||||
|
bytes memory initialRevertData
|
||||||
|
)
|
||||||
|
private
|
||||||
|
{
|
||||||
|
// Try the old AllowanceTarget.
|
||||||
|
try ITokenSpenderFeature(address(this))._spendERC20Tokens(
|
||||||
|
token,
|
||||||
|
owner,
|
||||||
|
to,
|
||||||
|
amount
|
||||||
|
) {
|
||||||
|
} catch (bytes memory revertData) {
|
||||||
|
// Bubble up the first error message. (In general, the fallback to the
|
||||||
|
// allowance target is opportunistic. We ignore the specific error
|
||||||
|
// message if it fails.)
|
||||||
|
LibSpenderRichErrors.SpenderERC20TransferFromFailedError(
|
||||||
|
address(token),
|
||||||
|
owner,
|
||||||
|
to,
|
||||||
|
amount,
|
||||||
|
initialRevertData.length != 0 ? initialRevertData : revertData
|
||||||
|
).rrevert();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -25,6 +25,7 @@ import "../features/TokenSpenderFeature.sol";
|
|||||||
import "../features/TransformERC20Feature.sol";
|
import "../features/TransformERC20Feature.sol";
|
||||||
import "../features/SignatureValidatorFeature.sol";
|
import "../features/SignatureValidatorFeature.sol";
|
||||||
import "../features/MetaTransactionsFeature.sol";
|
import "../features/MetaTransactionsFeature.sol";
|
||||||
|
import "../features/NativeOrdersFeature.sol";
|
||||||
import "../external/AllowanceTarget.sol";
|
import "../external/AllowanceTarget.sol";
|
||||||
import "./InitialMigration.sol";
|
import "./InitialMigration.sol";
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@ contract FullMigration {
|
|||||||
TransformERC20Feature transformERC20;
|
TransformERC20Feature transformERC20;
|
||||||
SignatureValidatorFeature signatureValidator;
|
SignatureValidatorFeature signatureValidator;
|
||||||
MetaTransactionsFeature metaTransactions;
|
MetaTransactionsFeature metaTransactions;
|
||||||
|
NativeOrdersFeature nativeOrders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Parameters needed to initialize features.
|
/// @dev Parameters needed to initialize features.
|
||||||
@@ -84,7 +86,7 @@ contract FullMigration {
|
|||||||
/// @param features Features to add to the proxy.
|
/// @param features Features to add to the proxy.
|
||||||
/// @return _zeroEx The configured ZeroEx contract. Same as the `zeroEx` parameter.
|
/// @return _zeroEx The configured ZeroEx contract. Same as the `zeroEx` parameter.
|
||||||
/// @param migrateOpts Parameters needed to initialize features.
|
/// @param migrateOpts Parameters needed to initialize features.
|
||||||
function initializeZeroEx(
|
function migrateZeroEx(
|
||||||
address payable owner,
|
address payable owner,
|
||||||
ZeroEx zeroEx,
|
ZeroEx zeroEx,
|
||||||
Features memory features,
|
Features memory features,
|
||||||
@@ -195,5 +197,16 @@ contract FullMigration {
|
|||||||
address(this)
|
address(this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// NativeOrdersFeature
|
||||||
|
{
|
||||||
|
// Register the feature.
|
||||||
|
ownable.migrate(
|
||||||
|
address(features.nativeOrders),
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
NativeOrdersFeature.migrate.selector
|
||||||
|
),
|
||||||
|
address(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "./LibStorage.sol";
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev Storage helpers for `NativeOrdersFeature`.
|
||||||
|
library LibNativeOrdersStorage {
|
||||||
|
|
||||||
|
/// @dev Storage bucket for this feature.
|
||||||
|
struct Storage {
|
||||||
|
// How much taker token has been filled in order.
|
||||||
|
// The lower `uint128` is the taker token fill amount.
|
||||||
|
// The high bit will be `1` if the order was directly cancelled.
|
||||||
|
mapping(bytes32 => uint256) orderHashToTakerTokenFilledAmount;
|
||||||
|
// The minimum valid order salt for a given maker and order pair (maker, taker)
|
||||||
|
// for limit orders.
|
||||||
|
mapping(address => mapping(address => mapping(address => uint256)))
|
||||||
|
limitOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt;
|
||||||
|
// The minimum valid order salt for a given maker and order pair (maker, taker)
|
||||||
|
// for RFQ orders.
|
||||||
|
mapping(address => mapping(address => mapping(address => uint256)))
|
||||||
|
rfqOrdersMakerToMakerTokenToTakerTokenToMinValidOrderSalt;
|
||||||
|
// For a given order origin, which tx.origin addresses are allowed to
|
||||||
|
// fill the order.
|
||||||
|
mapping(address => mapping(address => bool)) originRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Get the storage bucket for this contract.
|
||||||
|
function getStorage() internal pure returns (Storage storage stor) {
|
||||||
|
uint256 storageSlot = LibStorage.getStorageSlot(
|
||||||
|
LibStorage.StorageId.NativeOrders
|
||||||
|
);
|
||||||
|
// Dip into assembly to change the slot pointed to by the local
|
||||||
|
// variable `stor`.
|
||||||
|
// See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries
|
||||||
|
assembly { stor_slot := storageSlot }
|
||||||
|
}
|
||||||
|
}
|
@@ -36,7 +36,8 @@ library LibStorage {
|
|||||||
TokenSpender,
|
TokenSpender,
|
||||||
TransformERC20,
|
TransformERC20,
|
||||||
MetaTransactions,
|
MetaTransactions,
|
||||||
ReentrancyGuard
|
ReentrancyGuard,
|
||||||
|
NativeOrders
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Get the storage slot given a storage ID. We assign unique, well-spaced
|
/// @dev Get the storage slot given a storage ID. We assign unique, well-spaced
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user