Compare commits

...

41 Commits

Author SHA1 Message Date
Github Actions
64feeeea75 Publish
- @0x/contracts-asset-proxy@3.6.7
 - @0x/contracts-broker@1.1.15
 - @0x/contracts-coordinator@3.1.16
 - @0x/contracts-dev-utils@1.3.14
 - @0x/contracts-erc1155@2.1.16
 - @0x/contracts-erc20@3.2.10
 - @0x/contracts-erc721@3.1.16
 - @0x/contracts-exchange-forwarder@4.2.16
 - @0x/contracts-exchange-libs@4.3.16
 - @0x/contracts-exchange@3.2.16
 - @0x/contracts-extensions@6.2.10
 - @0x/contracts-integrations@2.7.11
 - @0x/contracts-multisig@4.1.16
 - @0x/contracts-staking@2.0.23
 - @0x/contracts-test-utils@5.3.13
 - @0x/contracts-utils@4.6.1
 - @0x/contracts-zero-ex@0.11.0
 - @0x/asset-swapper@5.3.0
 - @0x/contract-addresses@5.5.0
 - @0x/contract-artifacts@3.9.1
 - @0x/contract-wrappers-test@12.2.26
 - @0x/contract-wrappers@13.10.2
 - @0x/migrations@6.5.2
 - @0x/order-utils@10.4.8
2020-12-03 02:08:13 +00:00
Github Actions
2ebef23b8c Updated CHANGELOGS & MD docs 2020-12-03 02:08:07 +00:00
mzhu25
cc9f43ba3b Reenable PLP VIP and add gasCost field to LiquidityProviderRegistry (#65) 2020-12-02 17:26:48 -08:00
Xianny
5f1c139176 fix: handle potentially undefined path (#69)
* handle potentially undefined path

* Remove unused import

Co-authored-by: Michael Zhu <mchl.zhu.96@gmail.com>
2020-12-02 16:23:19 -08:00
mzhu25
9eea7de340 Point to ILiquidityProvider interface in docs, not ILiquidityProviderSandbox (#71) 2020-12-02 14:38:46 -08:00
Lawrence Forman
4480f84efa @0x/contracts-staking: Set isOfflineMode: false in compiler.json (#68)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-12-02 16:43:25 -05:00
Lawrence Forman
5a8b8afff1 Independent compilation for contracts-zero-ex package (#67)
* `@0x/contracts-zero-ex`: Update `compiler.json`

* update org deps and regen yarn lock

* fix `@0x/contracts-gen` being pinned (why?)

Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-12-02 11:14:19 -05:00
xianny
67c95bc0b7 add changelog and comments to pr #62 2020-12-01 13:05:21 -08:00
Greg Hysz
e70ec02be8 updated releases (#64) 2020-12-01 12:47:15 -08:00
Xianny
db81a94adb Return unoptimized quote in SwapQuote (#62)
* return unoptimized alternatives in SwapQuote

* refactor: dedupe
2020-12-01 12:40:48 -08:00
Lawrence Forman
475b608338 EP: FeeCollectorController (#59)
* `@0x/contracts-zero-ex`: Govern `FeeCollector`s through a separate `FeeCollectorController` contract.

* `@0x/contracts-integrations`: Fix broken EP protocol fees test.
`@0x/contracts-integrations`: Make this package private.

* `@0x/contract-addresses`: Update ganache snapshot addresses.

* Update contracts/zero-ex/contracts/src/external/FeeCollectorController.sol

Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>

* Apply suggestions from code review

Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>

* rebase

Co-authored-by: Lawrence Forman <me@merklejerk.com>
Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>
2020-12-01 12:17:21 -05:00
Jacob Evans
27e36b112e feat: [asset-swapper] support selling entire balance (#37) 2020-12-01 12:54:06 +10:00
Jacob Evans
f698721484 feat: [asset-swapper] Add Crypto.com as a source (#43)
* feat: [asset-swapper] Add Crypto.com as a source

* Exclude in tests

* Disable hop sources to avoid excess inaccuracy

* Added CryptoCom Bridge and FQT rollup

* update test

* Deploy CryptoCom bridge

* Update package.json

* CHANGELOGs
2020-12-01 12:52:48 +10:00
Daniel Pyrathon
0c08353b2c reanme function to Async (#63) 2020-11-30 17:02:28 -08:00
Greg Hysz
a074b49732 Added link to Transformer Deployer section + fixeed safety checklist in Features (#61) 2020-11-30 17:00:33 -08:00
Greg Hysz
43b75c7953 minor doc updates: include Best Practices for Feature Development. (#58) 2020-11-30 09:50:20 -08:00
Greg Hysz
84a78eafc4 minor doc improvements (#57) 2020-11-28 11:21:35 -08:00
Greg Hysz
3c1ab889dd V4 Docs. See live on https://0xprotocol.readthedocs.io. (#56) 2020-11-28 00:51:50 -08:00
Steve Marx
012fff46f6 add permissionless transformer deployer (#55)
* add permissionless transformer deployer
2020-11-27 18:21:49 -05:00
Greg Hysz
6307ebc3a2 Replace PairOrdersCancelled event with PairCancelledLimitOrders and PairCancelledRfqOrders (#54) 2020-11-27 13:31:12 -08:00
Steve Marx
88d7e73eba remove calldata signing (#51) 2020-11-25 16:55:12 -05:00
Steve Marx
9653eb9e70 RFQ order with 0 txOrigin is INVALID (#50) 2020-11-25 14:15:59 -05:00
Steve Marx
ad337271d3 Miscellaneous fixes to RFQ origin registration (#48)
* Contracts can no longer call registerAllowedRfqOrigins()
* registerAllowedRfqOrigins() is now plural, registers an array of
addresses
2020-11-25 14:08:15 -05:00
Lawrence Forman
7591e99316 Remove protocol fees from RFQ orders (#45)
* `@0x/contracts-zero-ex`: Remove protocol fees from native orders in certain scenarios.

* `@0x/contracts-zero-ex`: update changelog

* `@0x/contracts-zero-ex`: Add `taker` field to RFQ orders.`
`@0x/contracts-zero-ex`: Introduce protocol fees to all limit orders again.

* `@0x/contracts-zero-ex`: Rebase.

Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-11-24 18:24:06 -05:00
Lawrence Forman
ca20df4752 @0x/contracts-zero-ex: Fix TransformERC20Feature reverting when selling taker's entire balance when input token is ETH (#46)
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-11-24 17:52:22 -05:00
Steve Marx
841e4ee666 require txOrigin for RFQ orders, allow origins to register alternate … (#47)
require txOrigin for RFQ orders, allow origins to register alternate addresses that can fill orders
2020-11-24 16:53:32 -05:00
Steve Marx
e2ee3414ea limit order metatransactions (#44) 2020-11-24 13:39:40 -05:00
Steve Marx
5306cc03e9 Convert MetaTransactionsFeature to use the new LibSignature (#31) 2020-11-23 16:14:09 -05:00
F. Eugene Aumson
85f5d32de2 Allow injection of an RfqtFirmQuoteValidator and an RfqtQuoteObserver (#11)
* Allow injection of RFQT quote hooks

* Remove QuoteObserver

* Remove unnecessary `async`

* modernized the code based on latest spec

* prettify

Co-authored-by: Daniel Pyrathon <daniel@0x.org>
2020-11-23 12:05:28 -08:00
Lawrence Forman
ab698cec14 EP: misc fixes (#38)
* `@0x/contracts-zero-ex`: Fix NativeOrdersFeature order hash cancellation not emitting proper maker.
`@0x/contracts-zero-ex`: Revert to original (deployed) ZeroEx/EP proxy implementation. Optimized one is now at `ZeroExOptimized.sol`.
`@0x/contracts-zero-ex`: Add gas limits to first `transferFrom()` call in `LibTokenSpender` and `UniswapFeature`.

* `@0x/contracts-zero-ex`: Update changelog

* disable `no-empty-blocks` solidity linter rule

* `@0x/contracts-zero-ex`: Use bloom filters of greedy tokens in token transfer logic
`@0x/contracts-zero-ex`: Turn `LibTokenSpender` into `FixinTokenSpender`.
`@0x/contracts-zero-ex`: Misc renames for consistency.

* `@0x/contracts-zero-ex`: Export `GREEDY_TOKENS` list

* rebase and update changelog

* `@0x/contracts-zero-ex`: Change bloom filter hash algo based on discussions

* `@0x/contracts-zero-ex`: Fix changelog

* update orders docs

* `@0x/contracts-zero-ex`: revert if allowance call fails in uniswap feature

Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-11-23 12:59:02 -05:00
Steve Marx
b463a39bfa protocol fee / staking integration tests (#40) 2020-11-20 09:19:59 -05:00
Github Actions
018e25345b Publish
- @0x/contracts-asset-proxy@3.6.6
 - @0x/contracts-broker@1.1.14
 - @0x/contracts-coordinator@3.1.15
 - @0x/contracts-dev-utils@1.3.13
 - @0x/contracts-erc1155@2.1.15
 - @0x/contracts-erc20@3.2.9
 - @0x/contracts-erc721@3.1.15
 - @0x/contracts-exchange-forwarder@4.2.15
 - @0x/contracts-exchange-libs@4.3.15
 - @0x/contracts-exchange@3.2.15
 - @0x/contracts-extensions@6.2.9
 - @0x/contracts-integrations@2.7.10
 - @0x/contracts-multisig@4.1.15
 - @0x/contracts-staking@2.0.22
 - @0x/contracts-test-utils@5.3.12
 - @0x/contracts-utils@4.6.0
 - @0x/contracts-zero-ex@0.10.0
 - @0x/asset-swapper@5.2.0
 - @0x/contract-addresses@5.4.0
 - @0x/contract-wrappers-test@12.2.25
 - @0x/contract-wrappers@13.10.1
 - @0x/migrations@6.5.1
 - @0x/order-utils@10.4.7
2020-11-19 05:32:03 +00:00
Github Actions
b60fa8a7d7 Updated CHANGELOGS & MD docs 2020-11-19 05:31:53 +00:00
Jacob Evans
048d8dee60 fix: [asset-swapper] disable off-chain sampling for Balancer and CREAM (#41)
* fix: [asset-swapper] disable off-chain sampling for Balancer and CREAM

* Modify  Balancer off-chain test to expect only pools

* CHANGELOG
2020-11-19 15:00:09 +10:00
Alex Kroeger
927fe2b58b Improved ComparisonPrice function (#32)
* separated comparison price function into a new file, accounted for backup orders

* removed scratch code

* Adjusted documentation, object naming

* Refactored comparisonPrice function to use adjusted rate from optimizer, used native order fee schedule to adjust for order fees

* Small fixes to function, added unit tests

* Adjusted fee calculation for comparisonPrice function

* use available OptimalPathRate object

* fix lint error in test, separate out fee calculation

* Fixed market operation utils test, added additional checks for fee schedule

* removed unused dep, prettier
2020-11-18 17:12:35 -08:00
mzhu25
89948b360c Add checkAllowance flag to LibTokenSpender.spendERC20Tokens (#39) 2020-11-18 12:23:13 -08:00
Lawrence Forman
561b60a24d EP Native Orders (#27)
* `@0x/contracts-zero-ex`: add limit orders feature
`@0x/contracts-utils`: add `uint128` functions to `LibSafeMathV06`

* `@0x/contract-addresses`: Update ganache snapshot addresses

* `@0x/contracts-zero-ex`: Mask EIP712 struct hash values.

* `@0x/contracts-zero-ex`: Add more limit order tests

* `@0x/contracts-zero-ex`: Fix typos

* `@0x/contracts-zero-ex`: Compute fee collector address after protocol fee zero check.

* `@0x/contracts-zero-ex`: Remove WETH payment logic from fee collector fixin

* `@0x/contracts-zero-ex`: Convert all ETH to WETH in `FeeCollector`.

* `@0x/contracts-zero-ex`: Address review feedback

* `@0x/contracts-zero-ex`: Export more utils

* `@0x/contracts-zero-ex`: Rename `LimitOrdersFeatures`, `LibLimitOrders`, etc. into `*NativeOrders*`.
`@0x/contracts-zero-ex`: Emit `protocolFeePaid` in native order fill events.
`@0x/contracts-zero-ex`: Refactor to get around stack limits.
`@0x/contracts-zero-ex`: Use different storage mappings for RFQ and limit order pair cancellations.

* `@0x/contracts-zero-ex`: Add `getProtocolFeeMultiplier()` and `transferProtocolFeesForPools()` to `NativeOrdersFeature`.

* `@0x/contracts-zero-ex`: Fix broken tests

* update orders docs

* `@0x/contracts-zero-ex`: Add more tests to `NativeOrdersFeature`

* rebuild after rebase

* `@0x/contract-addresses`: Fix changelog booboo

* `@0x/contracts-zero-ex`: Add method selectors output to generated artifacts

* `@0x/contracts-zero-ex`: Add maker address to order cancel events.
`@0x/contracts-zreo-ex`: Remove `UpTo` suffix from order pair cancellation functions.
`@0x/contracts-zreo-ex`: Address misc review comments.

* `@0x/contracts-zero-ex`: More SafeMath in native orders

* update orders docs

Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-11-17 15:39:40 -05:00
Jacob Evans
4f82543bdf feat: asset-swapper tweak the gas schedule + return decimals (#34)
* feat: asset-swapper Return decimals from sampler in quote

* feat: asset-swapper tweak the gas schedule

* fix lint

* CHANGELOG
2020-11-17 11:36:53 +10:00
Github Actions
3133c509f9 Publish
- @0x/contracts-integrations@2.7.9
 - @0x/asset-swapper@5.1.1
2020-11-14 02:19:41 +00:00
Github Actions
426c15692d Updated CHANGELOGS & MD docs 2020-11-14 02:19:33 +00:00
mzhu25
8c87a77faa Remove PLP VIP path from EP swap quote consumer (#36) 2020-11-13 17:49:30 -08:00
288 changed files with 12735 additions and 4308 deletions

23
.readthedocs.yaml Normal file
View 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

View File

@@ -13,9 +13,11 @@
"indent": ["error", 4],
"max-line-length": ["warn", 160],
"no-inline-assembly": false,
"no-empty-blocks": false,
"quotes": ["error", "double"],
"separate-by-one-line-in-contract": "error",
"space-after-comma": "error",
"statement-indent": "error"
"statement-indent": "error",
"no-empty-blocks": false
}
}

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "3.6.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "3.6.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "3.6.5",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.6.7 - _December 3, 2020_
* Dependencies updated
## v3.6.6 - _November 19, 2020_
* Dependencies updated
## v3.6.5 - _November 13, 2020_
* Dependencies updated

View 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;
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-asset-proxy",
"version": "3.6.5",
"version": "3.6.7",
"engines": {
"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"
},
"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."
},
"repository": {
@@ -51,13 +51,13 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contract-wrappers": "^13.10.0",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contract-wrappers": "^13.10.2",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@types/lodash": "4.14.104",
@@ -79,17 +79,17 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/contracts-erc1155": "^2.1.14",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-erc721": "^3.1.14",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/order-utils": "^10.4.6",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"ethereum-types": "^3.3.3",
"@0x/base-contract": "^6.2.13",
"@0x/contracts-erc1155": "^2.1.16",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-erc721": "^3.1.16",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/order-utils": "^10.4.8",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"ethereum-types": "^3.4.0",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -9,6 +9,7 @@ import * as BalancerBridge from '../generated-artifacts/BalancerBridge.json';
import * as BancorBridge from '../generated-artifacts/BancorBridge.json';
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.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 DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json';
import * as DODOBridge from '../generated-artifacts/DODOBridge.json';
@@ -77,6 +78,7 @@ export const artifacts = {
BancorBridge: BancorBridge as ContractArtifact,
ChaiBridge: ChaiBridge as ContractArtifact,
CreamBridge: CreamBridge as ContractArtifact,
CryptoComBridge: CryptoComBridge as ContractArtifact,
CurveBridge: CurveBridge as ContractArtifact,
DODOBridge: DODOBridge as ContractArtifact,
DexForwarderBridge: DexForwarderBridge as ContractArtifact,

View File

@@ -7,6 +7,7 @@ export * from '../generated-wrappers/balancer_bridge';
export * from '../generated-wrappers/bancor_bridge';
export * from '../generated-wrappers/chai_bridge';
export * from '../generated-wrappers/cream_bridge';
export * from '../generated-wrappers/crypto_com_bridge';
export * from '../generated-wrappers/curve_bridge';
export * from '../generated-wrappers/d_o_d_o_bridge';
export * from '../generated-wrappers/dex_forwarder_bridge';

View File

@@ -9,6 +9,7 @@ import * as BalancerBridge from '../test/generated-artifacts/BalancerBridge.json
import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json';
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.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 DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json';
import * as DODOBridge from '../test/generated-artifacts/DODOBridge.json';
@@ -77,6 +78,7 @@ export const artifacts = {
BancorBridge: BancorBridge as ContractArtifact,
ChaiBridge: ChaiBridge as ContractArtifact,
CreamBridge: CreamBridge as ContractArtifact,
CryptoComBridge: CryptoComBridge as ContractArtifact,
CurveBridge: CurveBridge as ContractArtifact,
DODOBridge: DODOBridge as ContractArtifact,
DexForwarderBridge: DexForwarderBridge as ContractArtifact,

View File

@@ -7,6 +7,7 @@ export * from '../test/generated-wrappers/balancer_bridge';
export * from '../test/generated-wrappers/bancor_bridge';
export * from '../test/generated-wrappers/chai_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/d_o_d_o_bridge';
export * from '../test/generated-wrappers/dex_forwarder_bridge';

View File

@@ -7,6 +7,7 @@
"generated-artifacts/BancorBridge.json",
"generated-artifacts/ChaiBridge.json",
"generated-artifacts/CreamBridge.json",
"generated-artifacts/CryptoComBridge.json",
"generated-artifacts/CurveBridge.json",
"generated-artifacts/DODOBridge.json",
"generated-artifacts/DexForwarderBridge.json",
@@ -65,6 +66,7 @@
"test/generated-artifacts/BancorBridge.json",
"test/generated-artifacts/ChaiBridge.json",
"test/generated-artifacts/CreamBridge.json",
"test/generated-artifacts/CryptoComBridge.json",
"test/generated-artifacts/CurveBridge.json",
"test/generated-artifacts/DODOBridge.json",
"test/generated-artifacts/DexForwarderBridge.json",

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "1.1.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "1.1.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "1.1.13",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.1.15 - _December 3, 2020_
* Dependencies updated
## v1.1.14 - _November 19, 2020_
* Dependencies updated
## v1.1.13 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-broker",
"version": "1.1.13",
"version": "1.1.15",
"engines": {
"node": ">=6.12"
},
@@ -51,20 +51,20 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-erc721": "^3.1.14",
"@0x/contracts-exchange": "^3.2.14",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-erc721": "^3.1.16",
"@0x/contracts-exchange": "^3.2.16",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -84,11 +84,11 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/order-utils": "^10.4.6",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"ethereum-types": "^3.3.3"
"@0x/base-contract": "^6.2.13",
"@0x/order-utils": "^10.4.8",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"ethereum-types": "^3.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "3.1.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "3.1.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "3.1.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.1.16 - _December 3, 2020_
* Dependencies updated
## v3.1.15 - _November 19, 2020_
* Dependencies updated
## v3.1.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-coordinator",
"version": "3.1.14",
"version": "3.1.16",
"engines": {
"node": ">=6.12"
},
@@ -52,17 +52,17 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-dev-utils": "^1.3.12",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-gen": "2.0.18",
"@0x/dev-utils": "^4.0.1",
"@0x/order-utils": "^10.4.6",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-dev-utils": "^1.3.14",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-gen": "^2.0.23",
"@0x/dev-utils": "^4.1.2",
"@0x/order-utils": "^10.4.8",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/web3-wrapper": "^7.2.8",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -82,17 +82,17 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/assert": "^3.0.17",
"@0x/base-contract": "^6.2.11",
"@0x/contract-addresses": "^5.3.0",
"@0x/contracts-exchange": "^3.2.14",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/json-schemas": "^5.3.3",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"ethereum-types": "^3.3.3",
"@0x/assert": "^3.0.19",
"@0x/base-contract": "^6.2.13",
"@0x/contract-addresses": "^5.5.0",
"@0x/contracts-exchange": "^3.2.16",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/json-schemas": "^5.3.4",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"ethereum-types": "^3.4.0",
"http-status-codes": "^1.3.2"
},
"publishConfig": {

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "1.3.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "1.3.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "1.3.12",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v1.3.14 - _December 3, 2020_
* Dependencies updated
## v1.3.13 - _November 19, 2020_
* Dependencies updated
## v1.3.12 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-dev-utils",
"version": "1.3.12",
"version": "1.3.14",
"engines": {
"node": ">=6.12"
},
@@ -41,18 +41,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/dev-utils",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/assert": "^3.0.17",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/assert": "^3.0.19",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/utils": "^6.1.0",
"ethereum-types": "^3.3.3",
"@0x/types": "^3.3.1",
"@0x/utils": "^6.1.1",
"ethereum-types": "^3.4.0",
"ethers": "~4.0.4",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
@@ -63,7 +63,7 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/base-contract": "^6.2.13",
"@types/node": "12.12.54"
},
"publishConfig": {

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "2.1.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "2.1.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "2.1.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.1.16 - _December 3, 2020_
* Dependencies updated
## v2.1.15 - _November 19, 2020_
* Dependencies updated
## v2.1.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc1155",
"version": "2.1.14",
"version": "2.1.16",
"engines": {
"node": ">=6.12"
},
@@ -52,15 +52,15 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -68,7 +68,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.3.3",
"ethereum-types": "^3.4.0",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
"npm-run-all": "^4.1.2",
@@ -80,10 +80,10 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/base-contract": "^6.2.13",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "3.2.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "3.2.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "3.2.8",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.2.10 - _December 3, 2020_
* Dependencies updated
## v3.2.9 - _November 19, 2020_
* Dependencies updated
## v3.2.8 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc20",
"version": "3.2.8",
"version": "3.2.10",
"engines": {
"node": ">=6.12"
},
@@ -51,18 +51,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -70,7 +70,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.3.3",
"ethereum-types": "^3.4.0",
"lodash": "^4.17.11",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
@@ -82,7 +82,7 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11"
"@0x/base-contract": "^6.2.13"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "3.1.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "3.1.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "3.1.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.1.16 - _December 3, 2020_
* Dependencies updated
## v3.1.15 - _November 19, 2020_
* Dependencies updated
## v3.1.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-erc721",
"version": "3.1.14",
"version": "3.1.16",
"engines": {
"node": ">=6.12"
},
@@ -52,18 +52,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -71,7 +71,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.3.3",
"ethereum-types": "^3.4.0",
"lodash": "^4.17.11",
"make-promises-safe": "^1.1.0",
"mocha": "^6.2.0",
@@ -84,7 +84,7 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11"
"@0x/base-contract": "^6.2.13"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "4.2.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "4.2.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "4.2.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.2.16 - _December 3, 2020_
* Dependencies updated
## v4.2.15 - _November 19, 2020_
* Dependencies updated
## v4.2.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-exchange-forwarder",
"version": "4.2.14",
"version": "4.2.16",
"engines": {
"node": ">=6.12"
},
@@ -52,25 +52,25 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-dev-utils": "^1.3.12",
"@0x/contracts-erc1155": "^2.1.14",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-erc721": "^3.1.14",
"@0x/contracts-exchange": "^3.2.14",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/order-utils": "^10.4.6",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-dev-utils": "^1.3.14",
"@0x/contracts-erc1155": "^2.1.16",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-erc721": "^3.1.16",
"@0x/contracts-exchange": "^3.2.16",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/order-utils": "^10.4.8",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -90,9 +90,9 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/typescript-typings": "^5.1.5",
"ethereum-types": "^3.3.3"
"@0x/base-contract": "^6.2.13",
"@0x/typescript-typings": "^5.1.6",
"ethereum-types": "^3.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "4.3.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "4.3.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "4.3.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.3.16 - _December 3, 2020_
* Dependencies updated
## v4.3.15 - _November 19, 2020_
* Dependencies updated
## v4.3.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-exchange-libs",
"version": "4.3.14",
"version": "4.3.16",
"engines": {
"node": ">=6.12"
},
@@ -52,14 +52,14 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/libs",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-gen": "2.0.18",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/subproviders": "^6.1.9",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-gen": "^2.0.23",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/subproviders": "^6.2.2",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/web3-wrapper": "^7.2.8",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -80,14 +80,14 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/order-utils": "^10.4.6",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"ethereum-types": "^3.3.3"
"@0x/base-contract": "^6.2.13",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/order-utils": "^10.4.8",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"ethereum-types": "^3.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "3.2.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "3.2.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "3.2.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v3.2.16 - _December 3, 2020_
* Dependencies updated
## v3.2.15 - _November 19, 2020_
* Dependencies updated
## v3.2.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-exchange",
"version": "3.2.14",
"version": "3.2.16",
"engines": {
"node": ">=6.12"
},
@@ -52,21 +52,21 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-multisig": "^4.1.14",
"@0x/contracts-staking": "^2.0.21",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-multisig": "^4.1.16",
"@0x/contracts-staking": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -74,7 +74,7 @@
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.3.3",
"ethereum-types": "^3.4.0",
"ethereumjs-util": "^5.1.1",
"js-combinatorics": "^0.5.3",
"make-promises-safe": "^1.1.0",
@@ -88,13 +88,13 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/contracts-dev-utils": "^1.3.12",
"@0x/contracts-erc1155": "^2.1.14",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-erc721": "^3.1.14",
"@0x/order-utils": "^10.4.6",
"@0x/utils": "^6.1.0",
"@0x/base-contract": "^6.2.13",
"@0x/contracts-dev-utils": "^1.3.14",
"@0x/contracts-erc1155": "^2.1.16",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-erc721": "^3.1.16",
"@0x/order-utils": "^10.4.8",
"@0x/utils": "^6.1.1",
"lodash": "^4.17.11"
},
"publishConfig": {

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "6.2.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "6.2.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "6.2.8",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v6.2.10 - _December 3, 2020_
* Dependencies updated
## v6.2.9 - _November 19, 2020_
* Dependencies updated
## v6.2.8 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-extensions",
"version": "6.2.8",
"version": "6.2.10",
"engines": {
"node": ">=6.12"
},
@@ -52,23 +52,23 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-dev-utils": "^1.3.12",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-erc721": "^3.1.14",
"@0x/contracts-exchange": "^3.2.14",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/order-utils": "^10.4.6",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-dev-utils": "^1.3.14",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-erc721": "^3.1.16",
"@0x/contracts-exchange": "^3.2.16",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/order-utils": "^10.4.8",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -90,10 +90,10 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/typescript-typings": "^5.1.5",
"ethereum-types": "^3.3.3"
"@0x/base-contract": "^6.2.13",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/typescript-typings": "^5.1.6",
"ethereum-types": "^3.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -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,
"version": "2.7.8",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.7.10 - _November 19, 2020_
* Dependencies updated
## v2.7.9 - _November 14, 2020_
* Dependencies updated
## v2.7.8 - _November 13, 2020_
* Dependencies updated

View File

@@ -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
)
{}
}

View 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;
}
}

View File

@@ -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 {}

View File

@@ -1,6 +1,7 @@
{
"name": "@0x/contracts-integrations",
"version": "2.7.8",
"version": "2.7.11",
"private": true,
"engines": {
"node": ">=6.12"
},
@@ -38,7 +39,7 @@
},
"config": {
"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."
},
"repository": {
@@ -51,24 +52,24 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contract-addresses": "^5.3.0",
"@0x/contract-wrappers": "^13.10.0",
"@0x/contracts-broker": "^1.1.13",
"@0x/contracts-coordinator": "^3.1.14",
"@0x/contracts-dev-utils": "^1.3.12",
"@0x/contracts-exchange-forwarder": "^4.2.14",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/contracts-extensions": "^6.2.8",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-utils": "^4.5.8",
"@0x/abi-gen": "^5.4.12",
"@0x/contract-addresses": "^5.5.0",
"@0x/contract-wrappers": "^13.10.2",
"@0x/contracts-broker": "^1.1.15",
"@0x/contracts-coordinator": "^3.1.16",
"@0x/contracts-dev-utils": "^1.3.14",
"@0x/contracts-exchange-forwarder": "^4.2.16",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/contracts-extensions": "^6.2.10",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-utils": "^4.6.1",
"@0x/coordinator-server": "^1.0.5",
"@0x/dev-utils": "^4.0.1",
"@0x/migrations": "^6.5.0",
"@0x/order-utils": "^10.4.6",
"@0x/sol-compiler": "^4.2.7",
"@0x/dev-utils": "^4.1.2",
"@0x/migrations": "^6.5.2",
"@0x/order-utils": "^10.4.8",
"@0x/sol-compiler": "^4.4.0",
"@0x/tslint-config": "^4.1.3",
"@0x/web3-wrapper": "^7.2.8",
"@0x/web3-wrapper": "^7.2.10",
"@azure/core-asynciterator-polyfill": "^1.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -91,22 +92,22 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/asset-swapper": "^5.1.0",
"@0x/base-contract": "^6.2.11",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-erc1155": "^2.1.14",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-erc721": "^3.1.14",
"@0x/contracts-exchange": "^3.2.14",
"@0x/contracts-multisig": "^4.1.14",
"@0x/contracts-staking": "^2.0.21",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-zero-ex": "^0.9.0",
"@0x/subproviders": "^6.1.9",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"ethereum-types": "^3.3.3",
"@0x/asset-swapper": "^5.3.0",
"@0x/base-contract": "^6.2.13",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-erc1155": "^2.1.16",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-erc721": "^3.1.16",
"@0x/contracts-exchange": "^3.2.16",
"@0x/contracts-multisig": "^4.1.16",
"@0x/contracts-staking": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-zero-ex": "^0.11.0",
"@0x/subproviders": "^6.2.2",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"ethereum-types": "^3.4.0",
"ethereumjs-util": "^6.2.0",
"lodash": "^4.17.11"
},

View File

@@ -12,12 +12,15 @@ import * as TestContractWrapper from '../test/generated-artifacts/TestContractWr
import * as TestDydxUser from '../test/generated-artifacts/TestDydxUser.json';
import * as TestEth2Dai from '../test/generated-artifacts/TestEth2Dai.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 TestMainnetAggregatorFills from '../test/generated-artifacts/TestMainnetAggregatorFills.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 TestUniswapExchange from '../test/generated-artifacts/TestUniswapExchange.json';
import * as TestUniswapExchangeFactory from '../test/generated-artifacts/TestUniswapExchangeFactory.json';
import * as TestWethIntegration from '../test/generated-artifacts/TestWethIntegration.json';
export const artifacts = {
ChainlinkStopLimit: ChainlinkStopLimit as ContractArtifact,
IChainlinkAggregator: IChainlinkAggregator as ContractArtifact,
@@ -26,10 +29,13 @@ export const artifacts = {
TestDydxUser: TestDydxUser as ContractArtifact,
TestEth2Dai: TestEth2Dai as ContractArtifact,
TestEth2DaiBridge: TestEth2DaiBridge as ContractArtifact,
TestFixinProtocolFeesIntegration: TestFixinProtocolFeesIntegration as ContractArtifact,
TestFramework: TestFramework as ContractArtifact,
TestMainnetAggregatorFills: TestMainnetAggregatorFills as ContractArtifact,
TestSignatureValidationWallet: TestSignatureValidationWallet as ContractArtifact,
TestStaking: TestStaking as ContractArtifact,
TestUniswapBridge: TestUniswapBridge as ContractArtifact,
TestUniswapExchange: TestUniswapExchange as ContractArtifact,
TestUniswapExchangeFactory: TestUniswapExchangeFactory as ContractArtifact,
TestWethIntegration: TestWethIntegration as ContractArtifact,
};

View File

@@ -6,7 +6,7 @@ import {
artifacts as exchangeProxyArtifacts,
IZeroExContract,
LogMetadataTransformerContract,
signCallData,
Signature,
} from '@0x/contracts-zero-ex';
import { migrateOnceAsync } from '@0x/migrations';
import {
@@ -20,10 +20,19 @@ import {
SignedExchangeProxyMetaTransaction,
} from '@0x/order-utils';
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';
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 => {
const quoteSignerKey = hexUtils.random();
@@ -188,21 +197,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
.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(
data: string,
value: BigNumber,
@@ -232,15 +226,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 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 mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee, 0);
const mtx = await createMetaTransactionAsync(getSwapData(swap), _protocolFee, 0);
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
const receipt = await zeroEx
.executeMetaTransaction(mtx, mtx.signature)
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
const relayerEthRefund = relayerEthBalanceBefore
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
@@ -259,7 +251,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
[
{
taker,
callDataHash,
sender: zeroEx.address,
data: NULL_BYTES,
},
@@ -268,15 +259,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 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 mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee);
const mtx = await createMetaTransactionAsync(getSwapData(swap), _protocolFee);
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
const receipt = await zeroEx
.executeMetaTransaction(mtx, mtx.signature)
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
const relayerEthRefund = relayerEthBalanceBefore
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
@@ -295,7 +284,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
[
{
taker,
callDataHash,
sender: zeroEx.address,
data: NULL_BYTES,
},
@@ -304,51 +292,13 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
);
});
it('can call `transformERC20()` with wrongly signed calldata and a relayer fee', 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 () => {
it('`transformERC20()` can fill RFQT order', async () => {
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 mtx = await createMetaTransactionAsync(signedSwapData, _protocolFee, 0);
const mtx = await createMetaTransactionAsync(getSwapData(swap), _protocolFee, 0);
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
const receipt = await zeroEx
.executeMetaTransaction(mtx, mtx.signature)
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
const relayerEthRefund = relayerEthBalanceBefore
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
@@ -367,7 +317,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
[
{
taker,
callDataHash,
sender: zeroEx.address,
data: NULL_BYTES,
},
@@ -376,16 +325,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 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 mtx = await createMetaTransactionAsync(callData, _protocolFee, 0);
const relayerEthBalanceBefore = await env.web3Wrapper.getBalanceInWeiAsync(relayer);
await zeroEx.setQuoteSigner(NULL_ADDRESS).awaitTransactionSuccessAsync({ from: owner });
const receipt = await zeroEx
.executeMetaTransaction(mtx, mtx.signature)
.executeMetaTransaction(mtx, sigstruct(mtx.signature))
.awaitTransactionSuccessAsync({ from: relayer, value: mtx.value, gasPrice: GAS_PRICE });
const relayerEthRefund = relayerEthBalanceBefore
.minus(await env.web3Wrapper.getBalanceInWeiAsync(relayer))
@@ -404,7 +352,6 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
[
{
taker,
callDataHash,
sender: zeroEx.address,
data: NULL_BYTES,
},
@@ -412,15 +359,4 @@ blockchainTests.resets('exchange proxy - meta-transactions', env => {
'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());
});
});

View File

@@ -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_eth2_dai';
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_mainnet_aggregator_fills';
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_exchange';
export * from '../test/generated-wrappers/test_uniswap_exchange_factory';
export * from '../test/generated-wrappers/test_weth_integration';

View File

@@ -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));
});
});
});

View File

@@ -11,11 +11,14 @@
"test/generated-artifacts/TestDydxUser.json",
"test/generated-artifacts/TestEth2Dai.json",
"test/generated-artifacts/TestEth2DaiBridge.json",
"test/generated-artifacts/TestFixinProtocolFeesIntegration.json",
"test/generated-artifacts/TestFramework.json",
"test/generated-artifacts/TestMainnetAggregatorFills.json",
"test/generated-artifacts/TestSignatureValidationWallet.json",
"test/generated-artifacts/TestStaking.json",
"test/generated-artifacts/TestUniswapBridge.json",
"test/generated-artifacts/TestUniswapExchange.json",
"test/generated-artifacts/TestUniswapExchangeFactory.json"
"test/generated-artifacts/TestUniswapExchangeFactory.json",
"test/generated-artifacts/TestWethIntegration.json"
]
}

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "4.1.16",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "4.1.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "4.1.14",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v4.1.16 - _December 3, 2020_
* Dependencies updated
## v4.1.15 - _November 19, 2020_
* Dependencies updated
## v4.1.14 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-multisig",
"version": "4.1.14",
"version": "4.1.16",
"engines": {
"node": ">=6.12"
},
@@ -49,18 +49,18 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/sol-compiler": "^4.4.0",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
"@types/node": "12.12.54",
@@ -78,9 +78,9 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/typescript-typings": "^5.1.5",
"ethereum-types": "^3.3.3"
"@0x/base-contract": "^6.2.13",
"@0x/typescript-typings": "^5.1.6",
"ethereum-types": "^3.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "2.0.23",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "2.0.22",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "2.0.21",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v2.0.23 - _December 3, 2020_
* Dependencies updated
## v2.0.22 - _November 19, 2020_
* Dependencies updated
## v2.0.21 - _November 13, 2020_
* Dependencies updated

View File

@@ -2,7 +2,7 @@
"artifactsDir": "./test/generated-artifacts",
"contractsDir": "./contracts",
"useDockerisedSolc": false,
"isOfflineMode": true,
"isOfflineMode": false,
"shouldSaveStandardInput": true,
"compilerSettings": {
"evmVersion": "istanbul",

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-staking",
"version": "2.0.21",
"version": "2.0.23",
"engines": {
"node": ">=6.12"
},
@@ -53,20 +53,20 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-asset-proxy": "^3.6.5",
"@0x/contracts-dev-utils": "^1.3.12",
"@0x/contracts-erc20": "^3.2.8",
"@0x/contracts-exchange-libs": "^4.3.14",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-utils": "^4.5.8",
"@0x/dev-utils": "^4.0.1",
"@0x/order-utils": "^10.4.6",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-asset-proxy": "^3.6.7",
"@0x/contracts-dev-utils": "^1.3.14",
"@0x/contracts-erc20": "^3.2.10",
"@0x/contracts-exchange-libs": "^4.3.16",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-utils": "^4.6.1",
"@0x/dev-utils": "^4.1.2",
"@0x/order-utils": "^10.4.8",
"@0x/sol-compiler": "^4.4.0",
"@0x/ts-doc-gen": "^0.0.28",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/lodash": "4.14.104",
"@types/node": "12.12.54",
"chai": "^4.0.1",
@@ -87,11 +87,11 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"ethereum-types": "^3.3.3",
"@0x/base-contract": "^6.2.13",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"ethereum-types": "^3.4.0",
"ethereumjs-util": "^5.1.1"
},
"publishConfig": {

View File

@@ -1,4 +1,22 @@
[
{
"timestamp": 1606961263,
"version": "5.3.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605763885,
"version": "5.3.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1605302002,
"version": "5.3.11",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v5.3.13 - _December 3, 2020_
* Dependencies updated
## v5.3.12 - _November 19, 2020_
* Dependencies updated
## v5.3.11 - _November 13, 2020_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-test-utils",
"version": "5.3.11",
"version": "5.3.13",
"engines": {
"node": ">=6.12"
},
@@ -34,7 +34,7 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/test-utils",
"devDependencies": {
"@0x/sol-compiler": "^4.2.7",
"@0x/sol-compiler": "^4.4.0",
"@0x/tslint-config": "^4.1.3",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
@@ -42,20 +42,20 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/assert": "^3.0.17",
"@0x/base-contract": "^6.2.11",
"@0x/contract-addresses": "^5.3.0",
"@0x/dev-utils": "^4.0.1",
"@0x/json-schemas": "^5.3.3",
"@0x/order-utils": "^10.4.6",
"@0x/sol-coverage": "^4.0.18",
"@0x/sol-profiler": "^4.1.8",
"@0x/sol-trace": "^3.0.18",
"@0x/subproviders": "^6.1.9",
"@0x/types": "^3.3.0",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/assert": "^3.0.19",
"@0x/base-contract": "^6.2.13",
"@0x/contract-addresses": "^5.5.0",
"@0x/dev-utils": "^4.1.2",
"@0x/json-schemas": "^5.3.4",
"@0x/order-utils": "^10.4.8",
"@0x/sol-coverage": "^4.0.23",
"@0x/sol-profiler": "^4.1.13",
"@0x/sol-trace": "^3.0.23",
"@0x/subproviders": "^6.2.2",
"@0x/types": "^3.3.1",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/bn.js": "^4.11.0",
"@types/js-combinatorics": "^0.5.29",
"@types/lodash": "4.14.104",
@@ -67,7 +67,7 @@
"chai-bignumber": "^3.0.0",
"decimal.js": "^10.2.0",
"dirty-chai": "^2.0.1",
"ethereum-types": "^3.3.3",
"ethereum-types": "^3.4.0",
"ethereumjs-util": "^5.1.1",
"ethers": "~4.0.4",
"js-combinatorics": "^0.5.3",

View File

@@ -1,4 +1,23 @@
[
{
"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,
"version": "4.5.8",

View File

@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## 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_
* Dependencies updated

View File

@@ -105,4 +105,86 @@ library LibSafeMathV06 {
{
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;
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@0x/contracts-utils",
"version": "4.5.8",
"version": "4.6.1",
"engines": {
"node": ">=6.12"
},
@@ -50,15 +50,15 @@
},
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/utils",
"devDependencies": {
"@0x/abi-gen": "^5.4.7",
"@0x/contracts-gen": "2.0.18",
"@0x/contracts-test-utils": "^5.3.11",
"@0x/dev-utils": "^4.0.1",
"@0x/order-utils": "^10.4.6",
"@0x/sol-compiler": "^4.2.7",
"@0x/abi-gen": "^5.4.12",
"@0x/contracts-gen": "^2.0.23",
"@0x/contracts-test-utils": "^5.3.13",
"@0x/dev-utils": "^4.1.2",
"@0x/order-utils": "^10.4.8",
"@0x/sol-compiler": "^4.4.0",
"@0x/tslint-config": "^4.1.3",
"@0x/types": "^3.3.0",
"@0x/web3-wrapper": "^7.2.8",
"@0x/types": "^3.3.1",
"@0x/web3-wrapper": "^7.2.10",
"@types/bn.js": "^4.11.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^5.2.7",
@@ -79,11 +79,11 @@
"typescript": "3.0.1"
},
"dependencies": {
"@0x/base-contract": "^6.2.11",
"@0x/typescript-typings": "^5.1.5",
"@0x/utils": "^6.1.0",
"@0x/base-contract": "^6.2.13",
"@0x/typescript-typings": "^5.1.6",
"@0x/utils": "^6.1.1",
"bn.js": "^4.11.8",
"ethereum-types": "^3.3.3"
"ethereum-types": "^3.4.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,88 @@
[
{
"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",
"changes": [
@@ -55,6 +139,10 @@
{
"note": "Add `LibSignature` library",
"pr": 21
},
{
"note": "Add `LimitOrdersFeature`",
"pr": 27
}
],
"timestamp": 1604355662

View File

@@ -5,6 +5,30 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## 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_
* Rewrite the ZeroEx contract in Yul (#23)
@@ -25,6 +49,7 @@ CHANGELOG
* Add support for collecting protocol fees in ETH or WETH (#2)
* Add `LibSignature` library (#21)
* Add `LimitOrdersFeature` (#27)
## v0.5.1 - _October 28, 2020_

View File

@@ -4,6 +4,7 @@
"useDockerisedSolc": false,
"isOfflineMode": false,
"shouldSaveStandardInput": true,
"shouldCompileIndependently": true,
"compilerSettings": {
"evmVersion": "istanbul",
"optimizer": {
@@ -19,7 +20,8 @@
"evm.bytecode.object",
"evm.bytecode.sourceMap",
"evm.deployedBytecode.object",
"evm.deployedBytecode.sourceMap"
"evm.deployedBytecode.sourceMap",
"evm.methodIdentifiers"
]
}
}

View File

@@ -27,6 +27,7 @@ import "./features/ITransformERC20Feature.sol";
import "./features/IMetaTransactionsFeature.sol";
import "./features/IUniswapFeature.sol";
import "./features/ILiquidityProviderFeature.sol";
import "./features/INativeOrdersFeature.sol";
/// @dev Interface for a fully featured Exchange Proxy.
@@ -38,7 +39,8 @@ interface IZeroEx is
ITransformERC20Feature,
IMetaTransactionsFeature,
IUniswapFeature,
ILiquidityProviderFeature
ILiquidityProviderFeature,
INativeOrdersFeature
{
// solhint-disable state-visibility

View File

@@ -19,12 +19,19 @@
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
import "./migrations/LibBootstrap.sol";
import "./features/BootstrapFeature.sol";
import "./storage/LibProxyStorage.sol";
import "./errors/LibProxyRichErrors.sol";
/// @dev An extensible proxy contract that serves as a universal entry point for
/// interacting with the 0x protocol.
contract ZeroEx {
// solhint-disable separate-by-one-line-in-contract,indent,var-name-mixedcase
using LibBytesV06 for bytes;
/// @dev Construct this contract and register the `BootstrapFeature` feature.
/// After constructing this contract, `bootstrap()` should be called
/// by `bootstrap()` to seed the initial feature set.
@@ -37,55 +44,48 @@ contract ZeroEx {
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)
bytes4 selector = msg.data.readBytes4(0);
address impl = getFunctionImplementation(selector);
if (impl == address(0)) {
_revertWithData(LibProxyRichErrors.NotImplementedError(selector));
}
(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)) }
}
}

View 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)
}
}
}

View File

@@ -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
);
}
}

View File

@@ -58,8 +58,8 @@ contract FeeCollector is AuthorizableV06 {
onlyAuthorized
{
// Leave 1 wei behind to avoid expensive zero-->non-zero state change.
if (address(this).balance > 1) {
weth.deposit{value: address(this).balance - 1}();
if (address(this).balance > 0) {
weth.deposit{value: address(this).balance}();
}
}
}

View 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
));
}
}

View 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
))));
}
}

View 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.
}
}

View File

@@ -20,11 +20,10 @@ pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "./libs/LibSignature.sol";
/// @dev Meta-transactions feature.
interface IMetaTransactionsFeature {
/// @dev Describes an exchange proxy meta transaction.
struct MetaTransactionData {
// 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.
function executeMetaTransaction(
MetaTransactionData calldata mtx,
bytes calldata signature
LibSignature.Signature calldata signature
)
external
payable
@@ -80,7 +79,7 @@ interface IMetaTransactionsFeature {
/// @return returnResults The ABI-encoded results of the underlying calls.
function batchExecuteMetaTransactions(
MetaTransactionData[] calldata mtxs,
bytes[] calldata signatures
LibSignature.Signature[] calldata signatures
)
external
payable
@@ -88,14 +87,14 @@ interface IMetaTransactionsFeature {
/// @dev Execute a meta-transaction via `sender`. Privileged variant.
/// 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 signature The signature by `mtx.signer`.
/// @return returnResult The ABI-encoded result of the underlying call.
function _executeMetaTransaction(
address sender,
MetaTransactionData calldata mtx,
bytes calldata signature
MetaTransactionData memory mtx,
LibSignature.Signature memory signature
)
external
payable

View File

@@ -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);
}

View File

@@ -57,12 +57,4 @@ interface ISimpleFunctionRegistryFeature {
external
view
returns (address impl);
/// @dev Get the implementation contract of a registered function.
/// @param selector The function selector.
/// @return impl The implementation contract address.
function getFunctionImplementation(bytes4 selector)
external
view
returns (address impl);
}

View File

@@ -58,10 +58,6 @@ interface ITransformERC20Feature {
// The transformations to execute on the token balance(s)
// in sequence.
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`.

View File

@@ -26,16 +26,17 @@ import "../errors/LibLiquidityProviderRichErrors.sol";
import "../external/ILiquidityProviderSandbox.sol";
import "../external/LiquidityProviderSandbox.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinTokenSpender.sol";
import "../migrations/LibMigrate.sol";
import "./IFeature.sol";
import "./ILiquidityProviderFeature.sol";
import "./libs/LibTokenSpender.sol";
contract LiquidityProviderFeature is
IFeature,
ILiquidityProviderFeature,
FixinCommon
FixinCommon,
FixinTokenSpender
{
using LibSafeMathV06 for uint256;
using LibRichErrorsV06 for bytes;
@@ -43,7 +44,7 @@ contract LiquidityProviderFeature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "LiquidityProviderFeature";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 1);
/// @dev ETH pseudo-token address.
address constant internal ETH_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
@@ -60,11 +61,12 @@ contract LiquidityProviderFeature is
address recipient
);
constructor(address zeroEx)
constructor(LiquidityProviderSandbox sandbox_, bytes32 greedyTokensBloomFilter)
public
FixinCommon()
FixinTokenSpender(greedyTokensBloomFilter)
{
sandbox = new LiquidityProviderSandbox(zeroEx);
sandbox = sandbox_;
}
/// @dev Initialize and register this feature.
@@ -112,7 +114,7 @@ contract LiquidityProviderFeature is
if (inputToken == ETH_TOKEN_ADDRESS) {
provider.transfer(sellAmount);
} else {
LibTokenSpender.spendERC20Tokens(
_transferERC20Tokens(
IERC20TokenV06(inputToken),
msg.sender,
provider,

View File

@@ -25,16 +25,16 @@ import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../errors/LibMetaTransactionsRichErrors.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinReentrancyGuard.sol";
import "../fixins/FixinTokenSpender.sol";
import "../fixins/FixinEIP712.sol";
import "../migrations/LibMigrate.sol";
import "../storage/LibMetaTransactionsStorage.sol";
import "./libs/LibSignedCallData.sol";
import "./IMetaTransactionsFeature.sol";
import "./ITransformERC20Feature.sol";
import "./libs/LibSignature.sol";
import "./ISignatureValidatorFeature.sol";
import "./IFeature.sol";
import "./libs/LibTokenSpender.sol";
import "./INativeOrdersFeature.sol";
/// @dev MetaTransactions feature.
contract MetaTransactionsFeature is
@@ -42,13 +42,13 @@ contract MetaTransactionsFeature is
IMetaTransactionsFeature,
FixinCommon,
FixinReentrancyGuard,
FixinEIP712
FixinEIP712,
FixinTokenSpender
{
using LibBytesV06 for bytes;
using LibRichErrorsV06 for bytes;
/// @dev Intermediate state vars used by `_executeMetaTransactionPrivate()`
/// to avoid stack overflows.
/// @dev Describes the state of a meta transaction.
struct ExecuteState {
// Sender of the meta-transaction.
address sender;
@@ -57,7 +57,7 @@ contract MetaTransactionsFeature is
// The meta-transaction data.
MetaTransactionData mtx;
// The meta-transaction signature (by `mtx.signer`).
bytes signature;
LibSignature.Signature signature;
// The selector of the function being called.
bytes4 selector;
// The ETH balance of this contract before performing the call.
@@ -78,7 +78,7 @@ contract MetaTransactionsFeature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "MetaTransactions";
/// @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.
bytes32 public immutable MTX_EIP712_TYPEHASH = keccak256(
"MetaTransactionData("
@@ -105,10 +105,11 @@ contract MetaTransactionsFeature is
}
}
constructor(address zeroExAddress)
constructor(address zeroExAddress, bytes32 greedyTokensBloomFilter)
public
FixinCommon()
FixinEIP712(zeroExAddress)
FixinTokenSpender(greedyTokensBloomFilter)
{
// solhint-disable-next-line no-empty-blocks
}
@@ -135,7 +136,7 @@ contract MetaTransactionsFeature is
/// @return returnResult The ABI-encoded result of the underlying call.
function executeMetaTransaction(
MetaTransactionData memory mtx,
bytes memory signature
LibSignature.Signature memory signature
)
public
payable
@@ -144,11 +145,13 @@ contract MetaTransactionsFeature is
refundsAttachedEth
returns (bytes memory returnResult)
{
returnResult = _executeMetaTransactionPrivate(
msg.sender,
mtx,
signature
);
ExecuteState memory state;
state.sender = msg.sender;
state.mtx = mtx;
state.hash = getMetaTransactionHash(mtx);
state.signature = signature;
returnResult = _executeMetaTransactionPrivate(state);
}
/// @dev Execute multiple meta-transactions.
@@ -157,7 +160,7 @@ contract MetaTransactionsFeature is
/// @return returnResults The ABI-encoded results of the underlying calls.
function batchExecuteMetaTransactions(
MetaTransactionData[] memory mtxs,
bytes[] memory signatures
LibSignature.Signature[] memory signatures
)
public
payable
@@ -174,11 +177,13 @@ contract MetaTransactionsFeature is
}
returnResults = new bytes[](mtxs.length);
for (uint256 i = 0; i < mtxs.length; ++i) {
returnResults[i] = _executeMetaTransactionPrivate(
msg.sender,
mtxs[i],
signatures[i]
);
ExecuteState memory state;
state.sender = msg.sender;
state.mtx = mtxs[i];
state.hash = getMetaTransactionHash(mtxs[i]);
state.signature = signatures[i];
returnResults[i] = _executeMetaTransactionPrivate(state);
}
}
@@ -191,7 +196,7 @@ contract MetaTransactionsFeature is
function _executeMetaTransaction(
address sender,
MetaTransactionData memory mtx,
bytes memory signature
LibSignature.Signature memory signature
)
public
payable
@@ -199,7 +204,13 @@ contract MetaTransactionsFeature is
onlySelf
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.
@@ -251,24 +262,13 @@ contract MetaTransactionsFeature is
}
/// @dev Execute a meta-transaction by `sender`. Low-level, hidden variant.
/// @param sender Who is executing the meta-transaction..
/// @param mtx The meta-transaction.
/// @param signature The signature by `mtx.signer`.
/// @param state The `ExecuteState` for this metatransaction, with `sender`,
/// `hash`, `mtx`, and `signature` fields filled.
/// @return returnResult The ABI-encoded result of the underlying call.
function _executeMetaTransactionPrivate(
address sender,
MetaTransactionData memory mtx,
bytes memory signature
)
function _executeMetaTransactionPrivate(ExecuteState memory state)
private
returns (bytes memory returnResult)
{
ExecuteState memory state;
state.sender = sender;
state.hash = getMetaTransactionHash(mtx);
state.mtx = mtx;
state.signature = signature;
_validateMetaTransaction(state);
// 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;
// Pay the fee to the sender.
if (mtx.feeAmount > 0) {
LibTokenSpender.spendERC20Tokens(
mtx.feeToken,
mtx.signer,
sender,
mtx.feeAmount
if (state.mtx.feeAmount > 0) {
_transferERC20Tokens(
state.mtx.feeToken,
state.mtx.signer,
state.sender,
state.mtx.feeAmount
);
}
// 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) {
returnResult = _executeTransformERC20Call(state);
} else if (state.selector == INativeOrdersFeature.fillLimitOrder.selector) {
returnResult = _executeFillLimitOrderCall(state);
} else if (state.selector == INativeOrdersFeature.fillRfqOrder.selector) {
returnResult = _executeFillRfqOrderCall(state);
} else {
LibMetaTransactionsRichErrors
.MetaTransactionUnsupportedFunctionError(state.hash, state.selector)
@@ -299,8 +303,8 @@ contract MetaTransactionsFeature is
emit MetaTransactionExecuted(
state.hash,
state.selector,
mtx.signer,
mtx.sender
state.mtx.signer,
state.mtx.sender
);
}
@@ -347,18 +351,17 @@ contract MetaTransactionsFeature is
state.mtx.value
).rrevert();
}
// Must be signed by signer.
try
ISignatureValidatorFeature(address(this))
.validateHashSignature(state.hash, state.mtx.signer, state.signature)
{}
catch (bytes memory err) {
LibMetaTransactionsRichErrors
.MetaTransactionInvalidSignatureError(
state.hash,
state.signature,
err
).rrevert();
if (LibSignature.getSignerOfHash(state.hash, state.signature) !=
state.mtx.signer) {
LibSignatureRichErrors.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.WRONG_SIGNER,
state.hash,
state.mtx.signer,
// TODO: Remove this field from SignatureValidationError
// when rich reverts are part of the protocol repo.
""
).rrevert();
}
// Transaction must not have been already executed.
state.executedBlockNumber = LibMetaTransactionsStorage
@@ -429,10 +432,6 @@ contract MetaTransactionsFeature is
// Decode call args for `ITransformERC20Feature.transformERC20()` as a struct.
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).
return _callSelf(
state.hash,
@@ -444,15 +443,95 @@ contract MetaTransactionsFeature is
outputToken: args.outputToken,
inputTokenAmount: args.inputTokenAmount,
minOutputTokenAmount: args.minOutputTokenAmount,
transformations: args.transformations,
callDataHash: callDataHash,
callDataSignature: callDataSignature
transformations: args.transformations
})
),
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.
/// Warning: Do not let unadulterated `callData` into this function.
function _callSelf(bytes32 hash, bytes memory callData, uint256 value)

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,6 @@ contract SimpleFunctionRegistryFeature is
// Register getters.
_extend(this.getRollbackLength.selector, _implementation);
_extend(this.getRollbackEntryAtIndex.selector, _implementation);
_extend(this.getFunctionImplementation.selector, _implementation);
return LibBootstrap.BOOTSTRAP_SUCCESS;
}
@@ -152,18 +151,6 @@ contract SimpleFunctionRegistryFeature is
return LibSimpleFunctionRegistryStorage.getStorage().implHistory[selector][idx];
}
/// @dev Get the implementation contract of a registered function.
/// @param selector The function selector.
/// @return impl The implementation contract address.
function getFunctionImplementation(bytes4 selector)
external
override
view
returns (address impl)
{
return LibProxyStorage.getStorage().impls[selector];
}
/// @dev Register or replace a function.
/// @param selector The function selector.
/// @param impl The implementation contract for the function.

View File

@@ -25,24 +25,24 @@ import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../errors/LibTransformERC20RichErrors.sol";
import "../fixins/FixinCommon.sol";
import "../fixins/FixinTokenSpender.sol";
import "../migrations/LibMigrate.sol";
import "../external/IFlashWallet.sol";
import "../external/FlashWallet.sol";
import "../storage/LibTransformERC20Storage.sol";
import "../transformers/IERC20Transformer.sol";
import "../transformers/LibERC20Transformer.sol";
import "./libs/LibSignedCallData.sol";
import "./ITransformERC20Feature.sol";
import "./IFeature.sol";
import "./ISignatureValidatorFeature.sol";
import "./libs/LibTokenSpender.sol";
/// @dev Feature to composably transform between ERC20 tokens.
contract TransformERC20Feature is
IFeature,
ITransformERC20Feature,
FixinCommon
FixinCommon,
FixinTokenSpender
{
using LibSafeMathV06 for uint256;
using LibRichErrorsV06 for bytes;
@@ -58,7 +58,12 @@ contract TransformERC20Feature is
/// @dev Name of this feature.
string public constant override FEATURE_NAME = "TransformERC20";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 0);
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 3, 1);
constructor(bytes32 greedyTokensBloomFilter)
public
FixinTokenSpender(greedyTokensBloomFilter)
{}
/// @dev Initialize and register this feature.
/// Should be delegatecalled by `Migrate.migrate()`.
@@ -171,8 +176,6 @@ contract TransformERC20Feature is
payable
returns (uint256 outputTokenAmount)
{
(bytes32 callDataHash, bytes memory callDataSignature) =
LibSignedCallData.parseCallData(msg.data);
return _transformERC20Private(
TransformERC20Args({
taker: msg.sender,
@@ -180,9 +183,7 @@ contract TransformERC20Feature is
outputToken: outputToken,
inputTokenAmount: inputTokenAmount,
minOutputTokenAmount: minOutputTokenAmount,
transformations: transformations,
callDataHash: callDataHash,
callDataSignature: callDataSignature
transformations: transformations
})
);
}
@@ -208,13 +209,19 @@ contract TransformERC20Feature is
private
returns (uint256 outputTokenAmount)
{
// If the input token amount is -1, transform the taker's entire
// spendable balance.
// If the input token amount is -1 and we are not selling ETH,
// transform the taker's entire spendable balance.
if (args.inputTokenAmount == uint256(-1)) {
args.inputTokenAmount = LibTokenSpender.getSpendableERC20BalanceOf(
args.inputToken,
args.taker
);
if (LibERC20Transformer.isTokenETH(args.inputToken)) {
// We can't pull more ETH from the taker, so we just set the
// 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;
@@ -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.
for (uint256 i = 0; i < args.transformations.length; ++i) {
_executeTransformation(
state.wallet,
args.transformations[i],
state.transformerDeployer,
args.taker,
// Transformers will receive a null calldata hash if
// the calldata was not properly signed.
validCallDataHash
args.taker
);
}
}
@@ -317,7 +315,12 @@ contract TransformERC20Feature is
// Transfer input tokens.
if (!LibERC20Transformer.isTokenETH(inputToken)) {
// Token is not ETH, so pull ERC20 tokens.
LibTokenSpender.spendERC20Tokens(inputToken, from, to, amount);
_transferERC20Tokens(
inputToken,
from,
to,
amount
);
} else if (msg.value < amount) {
// Token is ETH, so the caller must attach enough ETH to the call.
LibTransformERC20RichErrors.InsufficientEthAttachedError(
@@ -332,13 +335,11 @@ contract TransformERC20Feature is
/// @param transformation The transformation.
/// @param transformerDeployer The address of the transformer deployer.
/// @param taker The taker address.
/// @param callDataHash Hash of the calldata.
function _executeTransformation(
IFlashWallet wallet,
Transformation memory transformation,
address transformerDeployer,
address payable taker,
bytes32 callDataHash
address payable taker
)
private
{
@@ -355,7 +356,6 @@ contract TransformERC20Feature is
abi.encodeWithSelector(
IERC20Transformer.transform.selector,
IERC20Transformer.TransformContext({
callDataHash: callDataHash,
sender: msg.sender,
taker: taker,
data: transformation.data

View File

@@ -38,6 +38,8 @@ contract UniswapFeature is
string public constant override FEATURE_NAME = "UniswapFeature";
/// @dev Version of this feature.
uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 1, 0);
/// @dev A bloom filter for tokens that consume all gas when `transferFrom()` fails.
bytes32 public immutable GREEDY_TOKENS_BLOOM_FILTER;
/// @dev WETH contract.
IEtherTokenV06 private immutable WETH;
/// @dev AllowanceTarget instance.
@@ -66,6 +68,8 @@ contract UniswapFeature is
uint256 constant private UNISWAP_PAIR_SWAP_CALL_SELECTOR_32 = 0x022c0d9f00000000000000000000000000000000000000000000000000000000;
// bytes4(keccak256("transferFrom(address,address,uint256)"))
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)"))
uint256 constant private WETH_WITHDRAW_CALL_SELECTOR_32 = 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000;
// bytes4(keccak256("deposit()"))
@@ -76,9 +80,15 @@ contract UniswapFeature is
/// @dev Construct this contract.
/// @param weth The WETH 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;
ALLOWANCE_TARGET = allowanceTarget;
GREEDY_TOKENS_BLOOM_FILTER = greedyTokensBloomFilter;
}
/// @dev Initialize and register this feature.
@@ -114,6 +124,7 @@ contract UniswapFeature is
// Load immutables onto the stack.
IEtherTokenV06 weth = WETH;
IAllowanceTarget allowanceTarget = ALLOWANCE_TARGET;
bytes32 greedyTokensBloomFilter = GREEDY_TOKENS_BLOOM_FILTER;
// Store some vars in memory to get around stack limits.
assembly {
@@ -125,6 +136,8 @@ contract UniswapFeature is
mstore(0xA40, weth)
// mload(0xA60) == ALLOWANCE_TARGET
mstore(0xA60, allowanceTarget)
// mload(0xA80) == GREEDY_TOKENS_BLOOM_FILTER
mstore(0xA80, greedyTokensBloomFilter)
}
}
@@ -155,52 +168,10 @@ contract UniswapFeature is
if iszero(i) {
switch eq(sellToken, ETH_TOKEN_ADDRESS_32)
case 0 {
case 0 { // Not selling ETH. Selling an ERC20 instead.
// For the first pair we need to transfer sellTokens into the
// pair contract.
mstore(0xB00, TRANSFER_FROM_CALL_SELECTOR_32)
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()
}
}
moveTakerTokensTo(sellToken, pair, sellAmount)
}
default {
// If selling ETH, we need to wrap it to WETH and transfer to the
@@ -389,6 +360,108 @@ contract UniswapFeature is
returndatacopy(0, 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 := call(gas(), token, 0, 0xB00, 0x44, 0xC00, 0x20)
if iszero(success) {
// Call to allowance() failed.
bubbleRevert()
}
// 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(
// Cap the gas limit to prvent all gas being consumed
// if the token reverts.
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.

View 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)
}
}
}

View File

@@ -38,7 +38,7 @@ library LibSignature {
/// 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;
/// @dev Allowed signature types.
/// @dev Allowed signature types.
enum SignatureType {
ILLEGAL,
INVALID,

View File

@@ -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);
}
}

View File

@@ -21,72 +21,74 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.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.
abstract contract FixinProtocolFees {
bytes32 immutable feeCollectorCodeHash;
constructor() internal {
feeCollectorCodeHash = keccak256(type(FeeCollector).creationCode);
}
/// @dev The protocol fee multiplier.
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
/// msg.value is non-zero, the fee will be paid in ETH. Otherwise,
/// this function attempts to transfer the fee in WETH. Either way,
/// The fee is stored in a per-pool fee collector contract.
/// @param poolId The pool ID for which a fee is being collected.
/// @param amount The amount of ETH/WETH to be collected.
/// @param weth The WETH token contract.
function _collectProtocolFee(
bytes32 poolId,
uint256 amount,
IERC20TokenV06 weth
constructor(
IEtherTokenV06 weth,
IStaking staking,
FeeCollectorController feeCollectorController,
uint32 protocolFeeMultiplier
)
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) {
// WETH
LibTokenSpender.spendERC20Tokens(weth, msg.sender, address(feeCollector), amount);
} else {
// ETH
(bool success,) = address(feeCollector).call{value: amount}("");
require(success, "FixinProtocolFees/ETHER_TRANSFER_FALIED");
/// @dev Collect the specified protocol fee in ETH.
/// The fee is stored in a per-pool fee collector contract.
/// @param poolId The pool ID for which a fee is being collected.
/// @return ethProtocolFeePaid How much protocol fee was collected in ETH.
function _collectProtocolFee(bytes32 poolId)
internal
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.
/// @param poolId Identifies the pool whose fees are being paid.
function _transferFeesForPool(
bytes32 poolId,
IStaking staking,
IEtherTokenV06 weth
)
function _transferFeesForPool(bytes32 poolId)
internal
{
FeeCollector feeCollector = _getFeeCollector(poolId);
uint256 codeSize;
assembly {
codeSize := extcodesize(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));
// This will create a FeeCollector contract (if necessary) and wrap
// fees for the pool ID.
FeeCollector feeCollector =
FEE_COLLECTOR_CONTROLLER.prepareFeeCollectorToPayFees(poolId);
// All fees in the fee collector should be in WETH now.
uint256 bal = WETH.balanceOf(address(feeCollector));
if (bal > 1) {
// Leave 1 wei behind to avoid high SSTORE cost of zero-->non-zero.
staking.payProtocolFee(
STAKING.payProtocolFee(
address(feeCollector),
address(feeCollector),
bal - 1);
@@ -95,20 +97,25 @@ abstract contract FixinProtocolFees {
/// @dev Compute the CREATE2 address for a fee collector.
/// @param poolId The fee collector's pool ID.
function _getFeeCollector(
bytes32 poolId
)
function _getFeeCollector(bytes32 poolId)
internal
view
returns (FeeCollector)
{
// Compute the CREATE2 address for the fee collector.
address payable addr = address(uint256(keccak256(abi.encodePacked(
byte(0xff),
address(this),
poolId, // pool ID is salt
feeCollectorCodeHash
))));
return FeeCollector(addr);
return FeeCollector(LibFeeCollector.getFeeCollectorAddress(
address(FEE_COLLECTOR_CONTROLLER),
FEE_COLLECTOR_INIT_CODE_HASH,
poolId
));
}
/// @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;
}
}

View File

@@ -19,23 +19,37 @@
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../../errors/LibSpenderRichErrors.sol";
import "../ITokenSpenderFeature.sol";
import "../features/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;
// Mask of the lower 20 bytes of a bytes32.
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`.
/// @param token The token to spend.
/// @param owner The owner of the tokens.
/// @param to The recipient of the tokens.
/// @param amount The amount of `token` to transfer.
function spendERC20Tokens(
function _transferERC20Tokens(
IERC20TokenV06 token,
address owner,
address to,
@@ -46,7 +60,25 @@ library LibTokenSpender {
bool success;
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 {
let ptr := mload(0x40) // free memory pointer
@@ -57,7 +89,15 @@ library LibTokenSpender {
mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
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()
@@ -88,25 +128,13 @@ library LibTokenSpender {
}
if (!success) {
// Try the old AllowanceTarget.
try ITokenSpenderFeature(address(this))._spendERC20Tokens(
token,
owner,
to,
amount
) {
} 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();
}
_transferFromLegacyAllowanceTarget(
token,
owner,
to,
amount,
revertData
);
}
}
@@ -115,7 +143,7 @@ library LibTokenSpender {
/// @param token The token to spend.
/// @param owner The owner of the tokens.
/// @return amount The amount of tokens that can be pulled.
function getSpendableERC20BalanceOf(
function _getSpendableERC20BalanceOf(
IERC20TokenV06 token,
address owner
)
@@ -128,4 +156,53 @@ library LibTokenSpender {
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();
}
}
}

View File

@@ -25,6 +25,7 @@ import "../features/TokenSpenderFeature.sol";
import "../features/TransformERC20Feature.sol";
import "../features/SignatureValidatorFeature.sol";
import "../features/MetaTransactionsFeature.sol";
import "../features/NativeOrdersFeature.sol";
import "../external/AllowanceTarget.sol";
import "./InitialMigration.sol";
@@ -42,6 +43,7 @@ contract FullMigration {
TransformERC20Feature transformERC20;
SignatureValidatorFeature signatureValidator;
MetaTransactionsFeature metaTransactions;
NativeOrdersFeature nativeOrders;
}
/// @dev Parameters needed to initialize features.
@@ -84,7 +86,7 @@ contract FullMigration {
/// @param features Features to add to the proxy.
/// @return _zeroEx The configured ZeroEx contract. Same as the `zeroEx` parameter.
/// @param migrateOpts Parameters needed to initialize features.
function initializeZeroEx(
function migrateZeroEx(
address payable owner,
ZeroEx zeroEx,
Features memory features,
@@ -195,5 +197,16 @@ contract FullMigration {
address(this)
);
}
// NativeOrdersFeature
{
// Register the feature.
ownable.migrate(
address(features.nativeOrders),
abi.encodeWithSelector(
NativeOrdersFeature.migrate.selector
),
address(this)
);
}
}
}

View File

@@ -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 }
}
}

View File

@@ -36,7 +36,8 @@ library LibStorage {
TokenSpender,
TransformERC20,
MetaTransactions,
ReentrancyGuard
ReentrancyGuard,
NativeOrders
}
/// @dev Get the storage slot given a storage ID. We assign unique, well-spaced

View File

@@ -180,10 +180,10 @@ contract FillQuoteTransformer is
state.protocolFee = exchange.protocolFeeMultiplier().safeMul(tx.gasprice);
state.ethRemaining = address(this).balance;
// RFQT orders can only be filled if we have a valid calldata hash
// (calldata was signed), and the actual taker matches the RFQT taker (if set).
state.isRfqtAllowed = context.callDataHash != bytes32(0)
&& (data.rfqtTakerAddress == address(0) || context.taker == data.rfqtTakerAddress);
// RFQT orders can only be filled if the actual taker matches the RFQT
// taker (if set).
state.isRfqtAllowed = data.rfqtTakerAddress == address(0)
|| context.taker == data.rfqtTakerAddress;
// Fill the orders.
for (uint256 i = 0; i < data.orders.length; ++i) {

View File

@@ -27,9 +27,6 @@ interface IERC20Transformer {
/// @dev Context information to pass into `transform()` by `TransformERC20.transformERC20()`.
struct TransformContext {
// The hash of the `TransformERC20.transformERC20()` calldata.
// Will be null if the calldata is not signed.
bytes32 callDataHash;
// The caller of `TransformERC20.transformERC20()`.
address payable sender;
// taker The taker address, which may be distinct from `sender` in the case

View File

@@ -27,7 +27,7 @@ import "./LibERC20Transformer.sol";
contract LogMetadataTransformer is
Transformer
{
event TransformerMetadata(bytes32 callDataHash, address sender, address taker, bytes data);
event TransformerMetadata(address sender, address taker, bytes data);
/// @dev Maximum uint256 value.
uint256 private constant MAX_UINT256 = uint256(-1);
@@ -40,7 +40,7 @@ contract LogMetadataTransformer is
override
returns (bytes4 success)
{
emit TransformerMetadata(context.callDataHash, context.sender, context.taker, context.data);
emit TransformerMetadata(context.sender, context.taker, context.data);
return LibERC20Transformer.TRANSFORMER_SUCCESS;
}
}

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "./mixins/MixinAdapterAddresses.sol";
import "./mixins/MixinBalancer.sol";
import "./mixins/MixinCurve.sol";
import "./mixins/MixinCryptoCom.sol";
import "./mixins/MixinDodo.sol";
import "./mixins/MixinKyber.sol";
import "./mixins/MixinMooniswap.sol";
@@ -37,6 +38,7 @@ contract BridgeAdapter is
MixinAdapterAddresses,
MixinBalancer,
MixinCurve,
MixinCryptoCom,
MixinDodo,
MixinKyber,
MixinMooniswap,
@@ -52,6 +54,7 @@ contract BridgeAdapter is
address private immutable BALANCER_BRIDGE_ADDRESS;
address private immutable CREAM_BRIDGE_ADDRESS;
address private immutable CURVE_BRIDGE_ADDRESS;
address private immutable CRYPTO_COM_BRIDGE_ADDRESS;
address private immutable DODO_BRIDGE_ADDRESS;
address private immutable KYBER_BRIDGE_ADDRESS;
address private immutable MOONISWAP_BRIDGE_ADDRESS;
@@ -68,6 +71,7 @@ contract BridgeAdapter is
public
MixinBalancer()
MixinCurve()
MixinCryptoCom(addresses)
MixinDodo(addresses)
MixinKyber(addresses)
MixinMooniswap(addresses)
@@ -81,6 +85,7 @@ contract BridgeAdapter is
{
BALANCER_BRIDGE_ADDRESS = addresses.balancerBridge;
CURVE_BRIDGE_ADDRESS = addresses.curveBridge;
CRYPTO_COM_BRIDGE_ADDRESS = addresses.cryptoComBridge;
KYBER_BRIDGE_ADDRESS = addresses.kyberBridge;
MOONISWAP_BRIDGE_ADDRESS = addresses.mooniswapBridge;
MSTABLE_BRIDGE_ADDRESS = addresses.mStableBridge;
@@ -185,6 +190,12 @@ contract BridgeAdapter is
sellAmount,
bridgeData
);
} else if (bridgeAddress == CRYPTO_COM_BRIDGE_ADDRESS) {
boughtAmount = _tradeCryptoCom(
buyToken,
sellAmount,
bridgeData
);
} else {
boughtAmount = _tradeZeroExBridge(
bridgeAddress,

View File

@@ -26,6 +26,7 @@ contract MixinAdapterAddresses
address balancerBridge;
address creamBridge;
address curveBridge;
address cryptoComBridge;
address dodoBridge;
address kyberBridge;
address mooniswapBridge;

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