Compare commits
13 Commits
protocol@7
...
@0x/contra
Author | SHA1 | Date | |
---|---|---|---|
|
a71c356bba | ||
|
c3a95b7fb1 | ||
|
f01540fb35 | ||
|
689a8881c2 | ||
|
99f5be8378 | ||
|
8de0282d92 | ||
|
f99804d56a | ||
|
f13d27b749 | ||
|
465fd59cbc | ||
|
5fdabe6612 | ||
|
861871134b | ||
|
c246d98093 | ||
|
02076dba1b |
48
.github/workflows/publish.yml
vendored
Normal file
48
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: publish
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ci_status:
|
||||
description: 'required CI status'
|
||||
default: 'success'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'check successful status'
|
||||
run: |
|
||||
REF_STATUS=$(curl -s \
|
||||
'https://api.github.com/repos/${{ github.repository }}/commits/${{ github.ref }}/status' \
|
||||
| jq .state)
|
||||
[[ "${REF_STATUS}" == '"${{ github.event.inputs.ci_status }}"' ]] || \
|
||||
(echo "::error ::${{ github.ref }} does not have a successful CI status" && false)
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'development'
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10
|
||||
- uses: actions/setup-python@v2
|
||||
- name: 'configure git'
|
||||
run: |
|
||||
git config --global user.email "github-actions@github.com"
|
||||
git config --global user.name "Github Actions"
|
||||
- name: 'install dependencies'
|
||||
run: |
|
||||
yarn -D
|
||||
- name: 'build and publish'
|
||||
run: |
|
||||
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > .npmrc
|
||||
npm run run:publish:gha
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: 'merge into main branch'
|
||||
run: |
|
||||
git checkout main && \
|
||||
git merge ${{ github.ref }} && \
|
||||
git push
|
@@ -1,4 +1,14 @@
|
||||
[
|
||||
{
|
||||
"version": "3.6.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add `SwerveBridge` and `SnowSwapBridge` (duplicate of `CurveBridge`)",
|
||||
"pr": 2707
|
||||
}
|
||||
],
|
||||
"timestamp": 1603833198
|
||||
},
|
||||
{
|
||||
"version": "3.5.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.6.0 - _October 27, 2020_
|
||||
|
||||
* Add `SwerveBridge` and `SnowSwapBridge` (duplicate of `CurveBridge`) (#2707)
|
||||
|
||||
## v3.5.0 - _October 21, 2020_
|
||||
|
||||
* Update `CurveBridge` to support more varied curves (#2633)
|
||||
|
119
contracts/asset-proxy/contracts/src/bridges/SnowSwapBridge.sol
Normal file
119
contracts/asset-proxy/contracts/src/bridges/SnowSwapBridge.sol
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
/*
|
||||
|
||||
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-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "../interfaces/IERC20Bridge.sol";
|
||||
import "../interfaces/ICurve.sol";
|
||||
|
||||
|
||||
// solhint-disable not-rely-on-time
|
||||
// solhint-disable space-after-comma
|
||||
contract SnowSwapBridge is
|
||||
IERC20Bridge,
|
||||
IWallet,
|
||||
DeploymentConstants
|
||||
{
|
||||
struct SnowSwapBridgeData {
|
||||
address curveAddress;
|
||||
bytes4 exchangeFunctionSelector;
|
||||
address fromTokenAddress;
|
||||
int128 fromCoinIdx;
|
||||
int128 toCoinIdx;
|
||||
}
|
||||
|
||||
/// @dev Callback for `ICurve`. Tries to buy `amount` of
|
||||
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
||||
/// (DAI, USDC) to the Curve contract, then transfers the bought
|
||||
/// tokens to `to`.
|
||||
/// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT).
|
||||
/// @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-encoeded "from" token address.
|
||||
/// @return success The magic bytes if successful.
|
||||
function bridgeTransferFrom(
|
||||
address toTokenAddress,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata bridgeData
|
||||
)
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Decode the bridge data to get the SnowSwap metadata.
|
||||
SnowSwapBridgeData memory data = abi.decode(bridgeData, (SnowSwapBridgeData));
|
||||
|
||||
require(toTokenAddress != data.fromTokenAddress, "SnowSwapBridge/INVALID_PAIR");
|
||||
uint256 fromTokenBalance = IERC20Token(data.fromTokenAddress).balanceOf(address(this));
|
||||
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
||||
LibERC20Token.approveIfBelow(data.fromTokenAddress, data.curveAddress, fromTokenBalance);
|
||||
|
||||
// Try to sell all of this contract's `fromTokenAddress` token balance.
|
||||
{
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
data.curveAddress.call(abi.encodeWithSelector(
|
||||
data.exchangeFunctionSelector,
|
||||
data.fromCoinIdx,
|
||||
data.toCoinIdx,
|
||||
// dx
|
||||
fromTokenBalance,
|
||||
// min dy
|
||||
amount
|
||||
));
|
||||
if (!didSucceed) {
|
||||
assembly { revert(add(resultData, 32), mload(resultData)) }
|
||||
}
|
||||
}
|
||||
|
||||
uint256 toTokenBalance = IERC20Token(toTokenAddress).balanceOf(address(this));
|
||||
// Transfer the converted `toToken`s to `to`.
|
||||
LibERC20Token.transfer(toTokenAddress, to, toTokenBalance);
|
||||
|
||||
emit ERC20BridgeTransfer(
|
||||
data.fromTokenAddress,
|
||||
toTokenAddress,
|
||||
fromTokenBalance,
|
||||
toTokenBalance,
|
||||
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 Magic success bytes, always.
|
||||
function isValidSignature(
|
||||
bytes32,
|
||||
bytes calldata
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bytes4 magicValue)
|
||||
{
|
||||
return LEGACY_WALLET_MAGIC_VALUE;
|
||||
}
|
||||
}
|
119
contracts/asset-proxy/contracts/src/bridges/SwerveBridge.sol
Normal file
119
contracts/asset-proxy/contracts/src/bridges/SwerveBridge.sol
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
/*
|
||||
|
||||
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-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "../interfaces/IERC20Bridge.sol";
|
||||
import "../interfaces/ICurve.sol";
|
||||
|
||||
|
||||
// solhint-disable not-rely-on-time
|
||||
// solhint-disable space-after-comma
|
||||
contract SwerveBridge is
|
||||
IERC20Bridge,
|
||||
IWallet,
|
||||
DeploymentConstants
|
||||
{
|
||||
struct SwerveBridgeData {
|
||||
address curveAddress;
|
||||
bytes4 exchangeFunctionSelector;
|
||||
address fromTokenAddress;
|
||||
int128 fromCoinIdx;
|
||||
int128 toCoinIdx;
|
||||
}
|
||||
|
||||
/// @dev Callback for `ICurve`. Tries to buy `amount` of
|
||||
/// `toTokenAddress` tokens by selling the entirety of the opposing asset
|
||||
/// (DAI, USDC) to the Curve contract, then transfers the bought
|
||||
/// tokens to `to`.
|
||||
/// @param toTokenAddress The token to give to `to` (i.e DAI, USDC, USDT).
|
||||
/// @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-encoeded "from" token address.
|
||||
/// @return success The magic bytes if successful.
|
||||
function bridgeTransferFrom(
|
||||
address toTokenAddress,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata bridgeData
|
||||
)
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Decode the bridge data to get the SwerveBridgeData metadata.
|
||||
SwerveBridgeData memory data = abi.decode(bridgeData, (SwerveBridgeData));
|
||||
|
||||
require(toTokenAddress != data.fromTokenAddress, "SwerveBridge/INVALID_PAIR");
|
||||
uint256 fromTokenBalance = IERC20Token(data.fromTokenAddress).balanceOf(address(this));
|
||||
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
||||
LibERC20Token.approveIfBelow(data.fromTokenAddress, data.curveAddress, fromTokenBalance);
|
||||
|
||||
// Try to sell all of this contract's `fromTokenAddress` token balance.
|
||||
{
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
data.curveAddress.call(abi.encodeWithSelector(
|
||||
data.exchangeFunctionSelector,
|
||||
data.fromCoinIdx,
|
||||
data.toCoinIdx,
|
||||
// dx
|
||||
fromTokenBalance,
|
||||
// min dy
|
||||
amount
|
||||
));
|
||||
if (!didSucceed) {
|
||||
assembly { revert(add(resultData, 32), mload(resultData)) }
|
||||
}
|
||||
}
|
||||
|
||||
uint256 toTokenBalance = IERC20Token(toTokenAddress).balanceOf(address(this));
|
||||
// Transfer the converted `toToken`s to `to`.
|
||||
LibERC20Token.transfer(toTokenAddress, to, toTokenBalance);
|
||||
|
||||
emit ERC20BridgeTransfer(
|
||||
data.fromTokenAddress,
|
||||
toTokenAddress,
|
||||
fromTokenBalance,
|
||||
toTokenBalance,
|
||||
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 Magic success bytes, always.
|
||||
function isValidSignature(
|
||||
bytes32,
|
||||
bytes calldata
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bytes4 magicValue)
|
||||
{
|
||||
return LEGACY_WALLET_MAGIC_VALUE;
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-asset-proxy",
|
||||
"version": "3.5.0",
|
||||
"version": "3.6.0",
|
||||
"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|StaticCallProxy|SushiSwapBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json",
|
||||
"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:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
@@ -52,10 +52,10 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contract-wrappers": "^13.9.0",
|
||||
"@0x/contract-wrappers": "^13.9.1",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -80,11 +80,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-erc1155": "^2.1.8",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc721": "^3.1.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/contracts-erc1155": "^2.1.9",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-erc721": "^3.1.9",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/types": "^3.2.4",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^5.6.3",
|
||||
|
@@ -47,8 +47,10 @@ import * as MStableBridge from '../generated-artifacts/MStableBridge.json';
|
||||
import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json';
|
||||
import * as Ownable from '../generated-artifacts/Ownable.json';
|
||||
import * as ShellBridge from '../generated-artifacts/ShellBridge.json';
|
||||
import * as SnowSwapBridge from '../generated-artifacts/SnowSwapBridge.json';
|
||||
import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json';
|
||||
import * as SushiSwapBridge from '../generated-artifacts/SushiSwapBridge.json';
|
||||
import * as SwerveBridge from '../generated-artifacts/SwerveBridge.json';
|
||||
import * as TestBancorBridge from '../generated-artifacts/TestBancorBridge.json';
|
||||
import * as TestChaiBridge from '../generated-artifacts/TestChaiBridge.json';
|
||||
import * as TestDexForwarderBridge from '../generated-artifacts/TestDexForwarderBridge.json';
|
||||
@@ -85,7 +87,9 @@ export const artifacts = {
|
||||
MixinGasToken: MixinGasToken as ContractArtifact,
|
||||
MooniswapBridge: MooniswapBridge as ContractArtifact,
|
||||
ShellBridge: ShellBridge as ContractArtifact,
|
||||
SnowSwapBridge: SnowSwapBridge as ContractArtifact,
|
||||
SushiSwapBridge: SushiSwapBridge as ContractArtifact,
|
||||
SwerveBridge: SwerveBridge as ContractArtifact,
|
||||
UniswapBridge: UniswapBridge as ContractArtifact,
|
||||
UniswapV2Bridge: UniswapV2Bridge as ContractArtifact,
|
||||
IAssetData: IAssetData as ContractArtifact,
|
||||
|
@@ -45,8 +45,10 @@ export * from '../generated-wrappers/mooniswap_bridge';
|
||||
export * from '../generated-wrappers/multi_asset_proxy';
|
||||
export * from '../generated-wrappers/ownable';
|
||||
export * from '../generated-wrappers/shell_bridge';
|
||||
export * from '../generated-wrappers/snow_swap_bridge';
|
||||
export * from '../generated-wrappers/static_call_proxy';
|
||||
export * from '../generated-wrappers/sushi_swap_bridge';
|
||||
export * from '../generated-wrappers/swerve_bridge';
|
||||
export * from '../generated-wrappers/test_bancor_bridge';
|
||||
export * from '../generated-wrappers/test_chai_bridge';
|
||||
export * from '../generated-wrappers/test_dex_forwarder_bridge';
|
||||
|
@@ -47,8 +47,10 @@ import * as MStableBridge from '../test/generated-artifacts/MStableBridge.json';
|
||||
import * as MultiAssetProxy from '../test/generated-artifacts/MultiAssetProxy.json';
|
||||
import * as Ownable from '../test/generated-artifacts/Ownable.json';
|
||||
import * as ShellBridge from '../test/generated-artifacts/ShellBridge.json';
|
||||
import * as SnowSwapBridge from '../test/generated-artifacts/SnowSwapBridge.json';
|
||||
import * as StaticCallProxy from '../test/generated-artifacts/StaticCallProxy.json';
|
||||
import * as SushiSwapBridge from '../test/generated-artifacts/SushiSwapBridge.json';
|
||||
import * as SwerveBridge from '../test/generated-artifacts/SwerveBridge.json';
|
||||
import * as TestBancorBridge from '../test/generated-artifacts/TestBancorBridge.json';
|
||||
import * as TestChaiBridge from '../test/generated-artifacts/TestChaiBridge.json';
|
||||
import * as TestDexForwarderBridge from '../test/generated-artifacts/TestDexForwarderBridge.json';
|
||||
@@ -85,7 +87,9 @@ export const artifacts = {
|
||||
MixinGasToken: MixinGasToken as ContractArtifact,
|
||||
MooniswapBridge: MooniswapBridge as ContractArtifact,
|
||||
ShellBridge: ShellBridge as ContractArtifact,
|
||||
SnowSwapBridge: SnowSwapBridge as ContractArtifact,
|
||||
SushiSwapBridge: SushiSwapBridge as ContractArtifact,
|
||||
SwerveBridge: SwerveBridge as ContractArtifact,
|
||||
UniswapBridge: UniswapBridge as ContractArtifact,
|
||||
UniswapV2Bridge: UniswapV2Bridge as ContractArtifact,
|
||||
IAssetData: IAssetData as ContractArtifact,
|
||||
|
@@ -45,8 +45,10 @@ export * from '../test/generated-wrappers/mooniswap_bridge';
|
||||
export * from '../test/generated-wrappers/multi_asset_proxy';
|
||||
export * from '../test/generated-wrappers/ownable';
|
||||
export * from '../test/generated-wrappers/shell_bridge';
|
||||
export * from '../test/generated-wrappers/snow_swap_bridge';
|
||||
export * from '../test/generated-wrappers/static_call_proxy';
|
||||
export * from '../test/generated-wrappers/sushi_swap_bridge';
|
||||
export * from '../test/generated-wrappers/swerve_bridge';
|
||||
export * from '../test/generated-wrappers/test_bancor_bridge';
|
||||
export * from '../test/generated-wrappers/test_chai_bridge';
|
||||
export * from '../test/generated-wrappers/test_dex_forwarder_bridge';
|
||||
|
@@ -45,8 +45,10 @@
|
||||
"generated-artifacts/MultiAssetProxy.json",
|
||||
"generated-artifacts/Ownable.json",
|
||||
"generated-artifacts/ShellBridge.json",
|
||||
"generated-artifacts/SnowSwapBridge.json",
|
||||
"generated-artifacts/StaticCallProxy.json",
|
||||
"generated-artifacts/SushiSwapBridge.json",
|
||||
"generated-artifacts/SwerveBridge.json",
|
||||
"generated-artifacts/TestBancorBridge.json",
|
||||
"generated-artifacts/TestChaiBridge.json",
|
||||
"generated-artifacts/TestDexForwarderBridge.json",
|
||||
@@ -101,8 +103,10 @@
|
||||
"test/generated-artifacts/MultiAssetProxy.json",
|
||||
"test/generated-artifacts/Ownable.json",
|
||||
"test/generated-artifacts/ShellBridge.json",
|
||||
"test/generated-artifacts/SnowSwapBridge.json",
|
||||
"test/generated-artifacts/StaticCallProxy.json",
|
||||
"test/generated-artifacts/SushiSwapBridge.json",
|
||||
"test/generated-artifacts/SwerveBridge.json",
|
||||
"test/generated-artifacts/TestBancorBridge.json",
|
||||
"test/generated-artifacts/TestChaiBridge.json",
|
||||
"test/generated-artifacts/TestDexForwarderBridge.json",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "1.1.8",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "1.1.7",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.8 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.7 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-broker",
|
||||
"version": "1.1.7",
|
||||
"version": "1.1.8",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,14 +52,14 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc721": "^3.1.8",
|
||||
"@0x/contracts-exchange": "^3.2.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-erc721": "^3.1.9",
|
||||
"@0x/contracts-exchange": "^3.2.9",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -85,7 +85,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^5.6.3",
|
||||
"ethereum-types": "^3.3.3"
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "3.1.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "3.1.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-coordinator",
|
||||
"version": "3.1.8",
|
||||
"version": "3.1.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,12 +53,12 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.6",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.7",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -84,10 +84,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.13",
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contract-addresses": "^4.12.0",
|
||||
"@0x/contracts-exchange": "^3.2.8",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contract-addresses": "^5.0.0",
|
||||
"@0x/contracts-exchange": "^3.2.9",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/json-schemas": "^5.2.3",
|
||||
"@0x/types": "^3.2.4",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "1.3.7",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "1.3.6",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.3.7 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.3.6 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-dev-utils",
|
||||
"version": "1.3.6",
|
||||
"version": "1.3.7",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -43,10 +43,10 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/assert": "^3.0.13",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "2.1.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "2.1.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.1.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.1.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc1155",
|
||||
"version": "2.1.8",
|
||||
"version": "2.1.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,7 +54,7 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -81,7 +81,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/utils": "^5.6.3",
|
||||
"@0x/web3-wrapper": "^7.2.4",
|
||||
"lodash": "^4.17.11"
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "3.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "3.2.2",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.3 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.2 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc20",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,8 +53,8 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "3.1.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "3.1.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.1.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.1.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-erc721",
|
||||
"version": "3.1.8",
|
||||
"version": "3.1.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,8 +54,8 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "4.2.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "4.2.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.2.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.2.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-forwarder",
|
||||
"version": "4.2.8",
|
||||
"version": "4.2.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,18 +53,18 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.6",
|
||||
"@0x/contracts-erc1155": "^2.1.8",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc721": "^3.1.8",
|
||||
"@0x/contracts-exchange": "^3.2.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.7",
|
||||
"@0x/contracts-erc1155": "^2.1.9",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-erc721": "^3.1.9",
|
||||
"@0x/contracts-exchange": "^3.2.9",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "4.3.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "4.3.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.3.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.3.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange-libs",
|
||||
"version": "4.3.8",
|
||||
"version": "4.3.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -81,9 +81,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/types": "^3.2.4",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^5.6.3",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "3.2.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "3.2.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.2.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.2.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-exchange",
|
||||
"version": "3.2.8",
|
||||
"version": "3.2.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,13 +53,13 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/protocol",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-multisig": "^4.1.8",
|
||||
"@0x/contracts-staking": "^2.0.15",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-multisig": "^4.1.9",
|
||||
"@0x/contracts-staking": "^2.0.16",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
@@ -89,11 +89,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-dev-utils": "^1.3.6",
|
||||
"@0x/contracts-erc1155": "^2.1.8",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc721": "^3.1.8",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.7",
|
||||
"@0x/contracts-erc1155": "^2.1.9",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-erc721": "^3.1.9",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/utils": "^5.6.3",
|
||||
"lodash": "^4.17.11"
|
||||
},
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "6.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "6.2.2",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v6.2.3 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v6.2.2 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "6.2.2",
|
||||
"version": "6.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -53,16 +53,16 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.6",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc721": "^3.1.8",
|
||||
"@0x/contracts-exchange": "^3.2.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.7",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-erc721": "^3.1.9",
|
||||
"@0x/contracts-exchange": "^3.2.9",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"ethereum-types": "^3.3.3"
|
||||
},
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "2.7.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603487270,
|
||||
"version": "2.7.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.7.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.7.2 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.7.1 - _October 23, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.7.0 - _October 21, 2020_
|
||||
|
||||
* Update curveBridge tests (#2633)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-integrations",
|
||||
"version": "2.7.0",
|
||||
"version": "2.7.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,20 +52,20 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/extensions",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contract-addresses": "^4.12.0",
|
||||
"@0x/contract-wrappers": "^13.9.0",
|
||||
"@0x/contracts-broker": "^1.1.7",
|
||||
"@0x/contracts-coordinator": "^3.1.8",
|
||||
"@0x/contracts-dev-utils": "^1.3.6",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.8",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/contracts-extensions": "^6.2.2",
|
||||
"@0x/contract-addresses": "^5.0.0",
|
||||
"@0x/contract-wrappers": "^13.9.1",
|
||||
"@0x/contracts-broker": "^1.1.8",
|
||||
"@0x/contracts-coordinator": "^3.1.9",
|
||||
"@0x/contracts-dev-utils": "^1.3.7",
|
||||
"@0x/contracts-exchange-forwarder": "^4.2.9",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/contracts-extensions": "^6.2.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/coordinator-server": "^1.0.5",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/migrations": "^6.4.1",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/migrations": "^6.4.3",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
"@0x/web3-wrapper": "^7.2.4",
|
||||
@@ -91,17 +91,17 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/asset-swapper": "0xProject/gitpkg-registry#0x-asset-swapper-v4.6.0-36546480b",
|
||||
"@0x/asset-swapper": "^4.8.0",
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-erc1155": "^2.1.8",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc721": "^3.1.8",
|
||||
"@0x/contracts-exchange": "^3.2.8",
|
||||
"@0x/contracts-multisig": "^4.1.8",
|
||||
"@0x/contracts-staking": "^2.0.15",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-zero-ex": "^0.3.0",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-erc1155": "^2.1.9",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-erc721": "^3.1.9",
|
||||
"@0x/contracts-exchange": "^3.2.9",
|
||||
"@0x/contracts-multisig": "^4.1.9",
|
||||
"@0x/contracts-staking": "^2.0.16",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-zero-ex": "^0.5.0",
|
||||
"@0x/subproviders": "^6.1.5",
|
||||
"@0x/types": "^3.2.4",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "4.1.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "4.1.8",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.1.9 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.1.8 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-multisig",
|
||||
"version": "4.1.8",
|
||||
"version": "4.1.9",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -50,11 +50,11 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/multisig",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "2.0.16",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "2.0.15",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.0.16 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.15 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-staking",
|
||||
"version": "2.0.15",
|
||||
"version": "2.0.16",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -54,14 +54,14 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/tokens",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-asset-proxy": "^3.5.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.6",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-exchange-libs": "^4.3.8",
|
||||
"@0x/contracts-asset-proxy": "^3.6.0",
|
||||
"@0x/contracts-dev-utils": "^1.3.7",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-exchange-libs": "^4.3.9",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-utils": "^4.5.2",
|
||||
"@0x/contracts-utils": "^4.5.3",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
@@ -88,7 +88,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/typescript-typings": "^5.1.5",
|
||||
"@0x/utils": "^5.6.3",
|
||||
"ethereum-types": "^3.3.3",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "5.3.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603265572,
|
||||
"version": "5.3.5",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v5.3.6 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.3.5 - _October 21, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-test-utils",
|
||||
"version": "5.3.5",
|
||||
"version": "5.3.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -44,10 +44,10 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^3.0.13",
|
||||
"@0x/base-contract": "^6.2.7",
|
||||
"@0x/contract-addresses": "^4.12.0",
|
||||
"@0x/contract-addresses": "^5.0.0",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/json-schemas": "^5.2.3",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-coverage": "^4.0.14",
|
||||
"@0x/sol-profiler": "^4.1.4",
|
||||
"@0x/sol-trace": "^3.0.14",
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1603833198,
|
||||
"version": "4.5.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.5.2",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.5.3 - _October 27, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.5.2 - _October 21, 2020_
|
||||
|
||||
* Add Ropsten and Rinkeby addresses to `DeploymentConstants` (#2656)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-utils",
|
||||
"version": "4.5.2",
|
||||
"version": "4.5.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -52,9 +52,9 @@
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
"@0x/types": "^3.2.4",
|
||||
|
@@ -1,4 +1,24 @@
|
||||
[
|
||||
{
|
||||
"version": "0.5.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add `Swerve`, `SnowSwap`, `DODO` and `SushiSwap` into FQT",
|
||||
"pr": 7
|
||||
}
|
||||
],
|
||||
"timestamp": 1603833198
|
||||
},
|
||||
{
|
||||
"version": "0.4.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Use the exchange proxy as the primary allowance target",
|
||||
"pr": 3
|
||||
}
|
||||
],
|
||||
"timestamp": 1603487270
|
||||
},
|
||||
{
|
||||
"version": "0.3.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.5.0 - _October 27, 2020_
|
||||
|
||||
* Add `Swerve`, `SnowSwap`, `DODO` and `SushiSwap` into FQT (#7)
|
||||
|
||||
## v0.4.0 - _October 23, 2020_
|
||||
|
||||
* Use the exchange proxy as the primary allowance target (#3)
|
||||
|
||||
## v0.3.0 - _October 21, 2020_
|
||||
|
||||
* Internal audit fixes (#2657)
|
||||
|
@@ -31,7 +31,7 @@ import "../storage/LibLiquidityProviderStorage.sol";
|
||||
import "../vendor/v3/IERC20Bridge.sol";
|
||||
import "./IFeature.sol";
|
||||
import "./ILiquidityProviderFeature.sol";
|
||||
import "./ITokenSpenderFeature.sol";
|
||||
import "./libs/LibTokenSpender.sol";
|
||||
|
||||
|
||||
contract LiquidityProviderFeature is
|
||||
@@ -97,7 +97,7 @@ contract LiquidityProviderFeature is
|
||||
weth.deposit{value: sellAmount}();
|
||||
weth.transfer(providerAddress, sellAmount);
|
||||
} else {
|
||||
ITokenSpenderFeature(address(this))._spendERC20Tokens(
|
||||
LibTokenSpender.spendERC20Tokens(
|
||||
IERC20TokenV06(takerToken),
|
||||
msg.sender,
|
||||
providerAddress,
|
||||
|
@@ -32,8 +32,8 @@ import "./libs/LibSignedCallData.sol";
|
||||
import "./IMetaTransactionsFeature.sol";
|
||||
import "./ITransformERC20Feature.sol";
|
||||
import "./ISignatureValidatorFeature.sol";
|
||||
import "./ITokenSpenderFeature.sol";
|
||||
import "./IFeature.sol";
|
||||
import "./libs/LibTokenSpender.sol";
|
||||
|
||||
|
||||
/// @dev MetaTransactions feature.
|
||||
@@ -279,10 +279,10 @@ contract MetaTransactionsFeature is
|
||||
|
||||
// Pay the fee to the sender.
|
||||
if (mtx.feeAmount > 0) {
|
||||
ITokenSpenderFeature(address(this))._spendERC20Tokens(
|
||||
LibTokenSpender.spendERC20Tokens(
|
||||
mtx.feeToken,
|
||||
mtx.signer, // From the signer.
|
||||
sender, // To the sender.
|
||||
mtx.signer,
|
||||
sender,
|
||||
mtx.feeAmount
|
||||
);
|
||||
}
|
||||
|
@@ -33,9 +33,9 @@ import "../transformers/IERC20Transformer.sol";
|
||||
import "../transformers/LibERC20Transformer.sol";
|
||||
import "./libs/LibSignedCallData.sol";
|
||||
import "./ITransformERC20Feature.sol";
|
||||
import "./ITokenSpenderFeature.sol";
|
||||
import "./IFeature.sol";
|
||||
import "./ISignatureValidatorFeature.sol";
|
||||
import "./libs/LibTokenSpender.sol";
|
||||
|
||||
|
||||
/// @dev Feature to composably transform between ERC20 tokens.
|
||||
@@ -211,8 +211,10 @@ contract TransformERC20Feature is
|
||||
// If the input token amount is -1, transform the taker's entire
|
||||
// spendable balance.
|
||||
if (args.inputTokenAmount == uint256(-1)) {
|
||||
args.inputTokenAmount = ITokenSpenderFeature(address(this))
|
||||
.getSpendableERC20BalanceOf(args.inputToken, args.taker);
|
||||
args.inputTokenAmount = LibTokenSpender.getSpendableERC20BalanceOf(
|
||||
args.inputToken,
|
||||
args.taker
|
||||
);
|
||||
}
|
||||
|
||||
TransformERC20PrivateState memory state;
|
||||
@@ -315,12 +317,7 @@ contract TransformERC20Feature is
|
||||
// Transfer input tokens.
|
||||
if (!LibERC20Transformer.isTokenETH(inputToken)) {
|
||||
// Token is not ETH, so pull ERC20 tokens.
|
||||
ITokenSpenderFeature(address(this))._spendERC20Tokens(
|
||||
inputToken,
|
||||
from,
|
||||
to,
|
||||
amount
|
||||
);
|
||||
LibTokenSpender.spendERC20Tokens(inputToken, from, to, amount);
|
||||
} else if (msg.value < amount) {
|
||||
// Token is ETH, so the caller must attach enough ETH to the call.
|
||||
LibTransformERC20RichErrors.InsufficientEthAttachedError(
|
||||
|
@@ -157,17 +157,49 @@ contract UniswapFeature is
|
||||
switch eq(sellToken, ETH_TOKEN_ADDRESS_32)
|
||||
case 0 {
|
||||
// For the first pair we need to transfer sellTokens into the
|
||||
// pair contract using `AllowanceTarget.executeCall()`
|
||||
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()
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
default {
|
||||
|
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
|
||||
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 "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
import "../../errors/LibSpenderRichErrors.sol";
|
||||
import "../ITokenSpenderFeature.sol";
|
||||
|
||||
library LibTokenSpender {
|
||||
using LibRichErrorsV06 for bytes;
|
||||
|
||||
/// @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(
|
||||
IERC20TokenV06 token,
|
||||
address owner,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
internal
|
||||
{
|
||||
bool success;
|
||||
bytes memory revertData;
|
||||
|
||||
require(address(token) != address(this), "LibTokenSpender/CANNOT_INVOKE_SELF");
|
||||
|
||||
assembly {
|
||||
let ptr := mload(0x40) // free memory pointer
|
||||
|
||||
// selector for transferFrom(address,address,uint256)
|
||||
mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
|
||||
mstore(add(ptr, 0x04), owner)
|
||||
mstore(add(ptr, 0x24), to)
|
||||
mstore(add(ptr, 0x44), amount)
|
||||
|
||||
success := call(gas(), token, 0, ptr, 0x64, 0, 0)
|
||||
|
||||
let rdsize := returndatasize()
|
||||
|
||||
returndatacopy(add(ptr, 0x20), 0, rdsize) // reuse memory
|
||||
|
||||
// Check for ERC20 success. ERC20 tokens should return a boolean,
|
||||
// but some don't. We accept 0-length return data as success, or at
|
||||
// least 32 bytes that starts with a 32-byte boolean true.
|
||||
success := and(
|
||||
success, // call itself succeeded
|
||||
or(
|
||||
iszero(rdsize), // no return data, or
|
||||
and(
|
||||
iszero(lt(rdsize, 32)), // at least 32 bytes
|
||||
eq(mload(add(ptr, 0x20)), 1) // starts with uint256(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if iszero(success) {
|
||||
// revertData is a bytes, so length-prefixed data
|
||||
mstore(ptr, rdsize)
|
||||
revertData := ptr
|
||||
|
||||
// update free memory pointer (ptr + 32-byte length + return data)
|
||||
mstore(0x40, add(add(ptr, 0x20), rdsize))
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Gets the maximum amount of an ERC20 token `token` that can be
|
||||
/// pulled from `owner` by this address.
|
||||
/// @param token The token to spend.
|
||||
/// @param owner The owner of the tokens.
|
||||
/// @return amount The amount of tokens that can be pulled.
|
||||
function getSpendableERC20BalanceOf(
|
||||
IERC20TokenV06 token,
|
||||
address owner
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return LibSafeMathV06.min256(
|
||||
token.allowance(owner, address(this)),
|
||||
token.balanceOf(owner)
|
||||
);
|
||||
}
|
||||
}
|
@@ -22,11 +22,13 @@ pragma experimental ABIEncoderV2;
|
||||
import "./mixins/MixinAdapterAddresses.sol";
|
||||
import "./mixins/MixinBalancer.sol";
|
||||
import "./mixins/MixinCurve.sol";
|
||||
import "./mixins/MixinDodo.sol";
|
||||
import "./mixins/MixinKyber.sol";
|
||||
import "./mixins/MixinMooniswap.sol";
|
||||
import "./mixins/MixinMStable.sol";
|
||||
import "./mixins/MixinOasis.sol";
|
||||
import "./mixins/MixinShell.sol";
|
||||
import "./mixins/MixinSushiswap.sol";
|
||||
import "./mixins/MixinUniswap.sol";
|
||||
import "./mixins/MixinUniswapV2.sol";
|
||||
import "./mixins/MixinZeroExBridge.sol";
|
||||
@@ -35,11 +37,13 @@ contract BridgeAdapter is
|
||||
MixinAdapterAddresses,
|
||||
MixinBalancer,
|
||||
MixinCurve,
|
||||
MixinDodo,
|
||||
MixinKyber,
|
||||
MixinMooniswap,
|
||||
MixinMStable,
|
||||
MixinOasis,
|
||||
MixinShell,
|
||||
MixinSushiswap,
|
||||
MixinUniswap,
|
||||
MixinUniswapV2,
|
||||
MixinZeroExBridge
|
||||
@@ -48,11 +52,15 @@ contract BridgeAdapter is
|
||||
address private immutable BALANCER_BRIDGE_ADDRESS;
|
||||
address private immutable CREAM_BRIDGE_ADDRESS;
|
||||
address private immutable CURVE_BRIDGE_ADDRESS;
|
||||
address private immutable DODO_BRIDGE_ADDRESS;
|
||||
address private immutable KYBER_BRIDGE_ADDRESS;
|
||||
address private immutable MOONISWAP_BRIDGE_ADDRESS;
|
||||
address private immutable MSTABLE_BRIDGE_ADDRESS;
|
||||
address private immutable OASIS_BRIDGE_ADDRESS;
|
||||
address private immutable SHELL_BRIDGE_ADDRESS;
|
||||
address private immutable SNOW_SWAP_BRIDGE_ADDRESS;
|
||||
address private immutable SUSHISWAP_BRIDGE_ADDRESS;
|
||||
address private immutable SWERVE_BRIDGE_ADDRESS;
|
||||
address private immutable UNISWAP_BRIDGE_ADDRESS;
|
||||
address private immutable UNISWAP_V2_BRIDGE_ADDRESS;
|
||||
|
||||
@@ -76,11 +84,13 @@ contract BridgeAdapter is
|
||||
public
|
||||
MixinBalancer()
|
||||
MixinCurve()
|
||||
MixinDodo(addresses)
|
||||
MixinKyber(addresses)
|
||||
MixinMooniswap(addresses)
|
||||
MixinMStable(addresses)
|
||||
MixinOasis(addresses)
|
||||
MixinShell(addresses)
|
||||
MixinSushiswap(addresses)
|
||||
MixinUniswap(addresses)
|
||||
MixinUniswapV2(addresses)
|
||||
MixinZeroExBridge()
|
||||
@@ -92,9 +102,13 @@ contract BridgeAdapter is
|
||||
MSTABLE_BRIDGE_ADDRESS = addresses.mStableBridge;
|
||||
OASIS_BRIDGE_ADDRESS = addresses.oasisBridge;
|
||||
SHELL_BRIDGE_ADDRESS = addresses.shellBridge;
|
||||
SUSHISWAP_BRIDGE_ADDRESS = addresses.sushiswapBridge;
|
||||
SWERVE_BRIDGE_ADDRESS = addresses.swerveBridge;
|
||||
UNISWAP_BRIDGE_ADDRESS = addresses.uniswapBridge;
|
||||
UNISWAP_V2_BRIDGE_ADDRESS = addresses.uniswapV2Bridge;
|
||||
CREAM_BRIDGE_ADDRESS = addresses.creamBridge;
|
||||
SNOW_SWAP_BRIDGE_ADDRESS = addresses.snowSwapBridge;
|
||||
DODO_BRIDGE_ADDRESS = addresses.dodoBridge;
|
||||
}
|
||||
|
||||
function trade(
|
||||
@@ -118,12 +132,20 @@ contract BridgeAdapter is
|
||||
"BridgeAdapter/INVALID_BRIDGE_ADDRESS"
|
||||
);
|
||||
|
||||
if (bridgeAddress == CURVE_BRIDGE_ADDRESS) {
|
||||
if (bridgeAddress == CURVE_BRIDGE_ADDRESS ||
|
||||
bridgeAddress == SWERVE_BRIDGE_ADDRESS ||
|
||||
bridgeAddress == SNOW_SWAP_BRIDGE_ADDRESS) {
|
||||
boughtAmount = _tradeCurve(
|
||||
buyToken,
|
||||
sellAmount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeAddress == SUSHISWAP_BRIDGE_ADDRESS) {
|
||||
boughtAmount = _tradeSushiswap(
|
||||
buyToken,
|
||||
sellAmount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeAddress == UNISWAP_V2_BRIDGE_ADDRESS) {
|
||||
boughtAmount = _tradeUniswapV2(
|
||||
buyToken,
|
||||
@@ -136,7 +158,8 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeAddress == BALANCER_BRIDGE_ADDRESS || bridgeAddress == CREAM_BRIDGE_ADDRESS) {
|
||||
} else if (bridgeAddress == BALANCER_BRIDGE_ADDRESS ||
|
||||
bridgeAddress == CREAM_BRIDGE_ADDRESS) {
|
||||
boughtAmount = _tradeBalancer(
|
||||
buyToken,
|
||||
sellAmount,
|
||||
@@ -172,6 +195,12 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeAddress == DODO_BRIDGE_ADDRESS) {
|
||||
boughtAmount = _tradeDodo(
|
||||
buyToken,
|
||||
sellAmount,
|
||||
bridgeData
|
||||
);
|
||||
} else {
|
||||
boughtAmount = _tradeZeroExBridge(
|
||||
bridgeAddress,
|
||||
|
@@ -26,20 +26,26 @@ contract MixinAdapterAddresses
|
||||
address balancerBridge;
|
||||
address creamBridge;
|
||||
address curveBridge;
|
||||
address dodoBridge;
|
||||
address kyberBridge;
|
||||
address mooniswapBridge;
|
||||
address mStableBridge;
|
||||
address oasisBridge;
|
||||
address shellBridge;
|
||||
address snowSwapBridge;
|
||||
address swerveBridge;
|
||||
address sushiswapBridge;
|
||||
address uniswapBridge;
|
||||
address uniswapV2Bridge;
|
||||
// Exchanges
|
||||
address kyberNetworkProxy;
|
||||
address oasis;
|
||||
address sushiswapRouter;
|
||||
address uniswapV2Router;
|
||||
address uniswapExchangeFactory;
|
||||
address mStable;
|
||||
address shell;
|
||||
address dodoHelper;
|
||||
// Other
|
||||
address weth;
|
||||
}
|
||||
|
@@ -0,0 +1,97 @@
|
||||
|
||||
/*
|
||||
|
||||
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/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "./MixinAdapterAddresses.sol";
|
||||
|
||||
interface IDODOHelper {
|
||||
|
||||
function querySellQuoteToken(address dodo, uint256 amount) external view returns (uint256);
|
||||
}
|
||||
|
||||
|
||||
interface IDODO {
|
||||
|
||||
function sellBaseToken(uint256 amount, uint256 minReceiveQuote, bytes calldata data) external returns (uint256);
|
||||
|
||||
function buyBaseToken(uint256 amount, uint256 maxPayQuote, bytes calldata data) external returns (uint256);
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract MixinDodo is
|
||||
MixinAdapterAddresses
|
||||
{
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
/// @dev Mainnet address of the `DOODO Helper` contract.
|
||||
IDODOHelper private immutable DODO_HELPER;
|
||||
|
||||
constructor(AdapterAddresses memory addresses)
|
||||
public
|
||||
{
|
||||
DODO_HELPER = IDODOHelper(addresses.dodoHelper);
|
||||
}
|
||||
|
||||
function _tradeDodo(
|
||||
IERC20TokenV06 /* buyToken */,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
(address fromTokenAddress,
|
||||
address pool,
|
||||
bool isSellBase) = abi.decode(bridgeData, (address, address, bool));
|
||||
|
||||
// Grant the Dodo pool contract an allowance to sell the first token.
|
||||
IERC20TokenV06(fromTokenAddress).approveIfBelow(pool, sellAmount);
|
||||
|
||||
if (isSellBase) {
|
||||
// Sell the Base token directly against the contract
|
||||
boughtAmount = IDODO(pool).sellBaseToken(
|
||||
// amount to sell
|
||||
sellAmount,
|
||||
// min receive amount
|
||||
1,
|
||||
new bytes(0)
|
||||
);
|
||||
} else {
|
||||
// Need to re-calculate the sell quote amount into buyBase
|
||||
boughtAmount = DODO_HELPER.querySellQuoteToken(
|
||||
pool,
|
||||
sellAmount
|
||||
);
|
||||
IDODO(pool).buyBaseToken(
|
||||
// amount to buy
|
||||
boughtAmount,
|
||||
// max pay amount
|
||||
sellAmount,
|
||||
new bytes(0)
|
||||
);
|
||||
}
|
||||
|
||||
return boughtAmount;
|
||||
}
|
||||
}
|
@@ -69,7 +69,7 @@ contract MixinShell is
|
||||
sellAmount
|
||||
);
|
||||
|
||||
uint256 buyAmount = SHELL.originSwap(
|
||||
boughtAmount = SHELL.originSwap(
|
||||
fromTokenAddress,
|
||||
address(buyToken),
|
||||
// Sell all tokens we hold.
|
||||
@@ -79,6 +79,6 @@ contract MixinShell is
|
||||
// deadline
|
||||
block.timestamp + 1
|
||||
);
|
||||
return buyAmount;
|
||||
return boughtAmount;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,79 @@
|
||||
|
||||
/*
|
||||
|
||||
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/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "./MixinAdapterAddresses.sol";
|
||||
import "./MixinUniswapV2.sol";
|
||||
|
||||
contract MixinSushiswap is
|
||||
MixinAdapterAddresses
|
||||
{
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
/// @dev Mainnet address of the `SushiswapRouter` contract.
|
||||
IUniswapV2Router02 private immutable SUSHISWAP_ROUTER;
|
||||
|
||||
constructor(AdapterAddresses memory addresses)
|
||||
public
|
||||
{
|
||||
SUSHISWAP_ROUTER = IUniswapV2Router02(addresses.sushiswapRouter);
|
||||
}
|
||||
|
||||
function _tradeSushiswap(
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
// solhint-disable indent
|
||||
address[] memory path = abi.decode(bridgeData, (address[]));
|
||||
// solhint-enable indent
|
||||
|
||||
require(path.length >= 2, "SushiswapBridge/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
|
||||
require(
|
||||
path[path.length - 1] == address(buyToken),
|
||||
"SushiswapBridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
|
||||
);
|
||||
// Grant the Uniswap router an allowance to sell the first token.
|
||||
IERC20TokenV06(path[0]).approveIfBelow(
|
||||
address(SUSHISWAP_ROUTER),
|
||||
sellAmount
|
||||
);
|
||||
|
||||
uint[] memory amounts = SUSHISWAP_ROUTER.swapExactTokensForTokens(
|
||||
// Sell all tokens we hold.
|
||||
sellAmount,
|
||||
// Minimum buy amount.
|
||||
1,
|
||||
// Convert to `buyToken` along this path.
|
||||
path,
|
||||
// Recipient is `this`.
|
||||
address(this),
|
||||
// Expires after this block.
|
||||
block.timestamp
|
||||
);
|
||||
return amounts[amounts.length-1];
|
||||
}
|
||||
}
|
72
contracts/zero-ex/contracts/test/TestLibTokenSpender.sol
Normal file
72
contracts/zero-ex/contracts/test/TestLibTokenSpender.sol
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
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 "../src/features/libs/LibTokenSpender.sol";
|
||||
|
||||
contract TestLibTokenSpender {
|
||||
uint256 constant private TRIGGER_FALLBACK_SUCCESS_AMOUNT = 1340;
|
||||
|
||||
function spendERC20Tokens(
|
||||
IERC20TokenV06 token,
|
||||
address owner,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
external
|
||||
{
|
||||
LibTokenSpender.spendERC20Tokens(token, owner, to, amount);
|
||||
}
|
||||
|
||||
event FallbackCalled(
|
||||
address token,
|
||||
address owner,
|
||||
address to,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
// This is called as a fallback when the original transferFrom() fails.
|
||||
function _spendERC20Tokens(
|
||||
IERC20TokenV06 token,
|
||||
address owner,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
external
|
||||
{
|
||||
require(amount == TRIGGER_FALLBACK_SUCCESS_AMOUNT,
|
||||
"TokenSpenderFallback/FAILURE_AMOUNT");
|
||||
|
||||
emit FallbackCalled(address(token), owner, to, amount);
|
||||
}
|
||||
|
||||
function getSpendableERC20BalanceOf(
|
||||
IERC20TokenV06 token,
|
||||
address owner
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return LibTokenSpender.getSpendableERC20BalanceOf(token, owner);
|
||||
}
|
||||
}
|
@@ -37,6 +37,9 @@ contract TestTokenSpenderERC20Token is
|
||||
uint256 constant private EMPTY_RETURN_AMOUNT = 1337;
|
||||
uint256 constant private FALSE_RETURN_AMOUNT = 1338;
|
||||
uint256 constant private REVERT_RETURN_AMOUNT = 1339;
|
||||
uint256 constant private TRIGGER_FALLBACK_SUCCESS_AMOUNT = 1340;
|
||||
uint256 constant private EXTRA_RETURN_TRUE_AMOUNT = 1341;
|
||||
uint256 constant private EXTRA_RETURN_FALSE_AMOUNT = 1342;
|
||||
|
||||
function transferFrom(address from, address to, uint256 amount)
|
||||
public
|
||||
@@ -53,6 +56,19 @@ contract TestTokenSpenderERC20Token is
|
||||
if (amount == REVERT_RETURN_AMOUNT) {
|
||||
revert("TestTokenSpenderERC20Token/Revert");
|
||||
}
|
||||
if (amount == TRIGGER_FALLBACK_SUCCESS_AMOUNT) {
|
||||
return false;
|
||||
}
|
||||
if (amount == EXTRA_RETURN_TRUE_AMOUNT
|
||||
|| amount == EXTRA_RETURN_FALSE_AMOUNT) {
|
||||
bool ret = amount == EXTRA_RETURN_TRUE_AMOUNT;
|
||||
|
||||
assembly {
|
||||
mstore(0x00, ret)
|
||||
mstore(0x20, amount) // just something extra to return
|
||||
return(0, 0x40)
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-zero-ex",
|
||||
"version": "0.3.0",
|
||||
"version": "0.5.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -41,7 +41,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,SignatureValidatorFeature,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinReentrancyGuard|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProviderFeature|IMetaTransactionsFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibLiquidityProviderStorage|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFullMigration|TestInitialMigration|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx).json"
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinReentrancyGuard|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProviderFeature|IMetaTransactionsFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibLiquidityProviderStorage|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpender|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFullMigration|TestInitialMigration|TestLibTokenSpender|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -54,11 +54,11 @@
|
||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^5.4.3",
|
||||
"@0x/contracts-erc20": "^3.2.2",
|
||||
"@0x/contracts-erc20": "^3.2.3",
|
||||
"@0x/contracts-gen": "2.0.13",
|
||||
"@0x/contracts-test-utils": "^5.3.5",
|
||||
"@0x/contracts-test-utils": "^5.3.6",
|
||||
"@0x/dev-utils": "^3.3.4",
|
||||
"@0x/order-utils": "^10.4.0",
|
||||
"@0x/order-utils": "^10.4.1",
|
||||
"@0x/sol-compiler": "^4.2.3",
|
||||
"@0x/ts-doc-gen": "^0.0.28",
|
||||
"@0x/tslint-config": "^4.1.3",
|
||||
|
@@ -54,6 +54,7 @@ import * as LibSimpleFunctionRegistryRichErrors from '../test/generated-artifact
|
||||
import * as LibSimpleFunctionRegistryStorage from '../test/generated-artifacts/LibSimpleFunctionRegistryStorage.json';
|
||||
import * as LibSpenderRichErrors from '../test/generated-artifacts/LibSpenderRichErrors.json';
|
||||
import * as LibStorage from '../test/generated-artifacts/LibStorage.json';
|
||||
import * as LibTokenSpender from '../test/generated-artifacts/LibTokenSpender.json';
|
||||
import * as LibTokenSpenderStorage from '../test/generated-artifacts/LibTokenSpenderStorage.json';
|
||||
import * as LibTransformERC20RichErrors from '../test/generated-artifacts/LibTransformERC20RichErrors.json';
|
||||
import * as LibTransformERC20Storage from '../test/generated-artifacts/LibTransformERC20Storage.json';
|
||||
@@ -64,11 +65,13 @@ import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransa
|
||||
import * as MixinAdapterAddresses from '../test/generated-artifacts/MixinAdapterAddresses.json';
|
||||
import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
|
||||
import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
|
||||
import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json';
|
||||
import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json';
|
||||
import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json';
|
||||
import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json';
|
||||
import * as MixinOasis from '../test/generated-artifacts/MixinOasis.json';
|
||||
import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
|
||||
import * as MixinSushiswap from '../test/generated-artifacts/MixinSushiswap.json';
|
||||
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
|
||||
import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json';
|
||||
import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridge.json';
|
||||
@@ -84,6 +87,7 @@ import * as TestFillQuoteTransformerExchange from '../test/generated-artifacts/T
|
||||
import * as TestFillQuoteTransformerHost from '../test/generated-artifacts/TestFillQuoteTransformerHost.json';
|
||||
import * as TestFullMigration from '../test/generated-artifacts/TestFullMigration.json';
|
||||
import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.json';
|
||||
import * as TestLibTokenSpender from '../test/generated-artifacts/TestLibTokenSpender.json';
|
||||
import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json';
|
||||
import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
|
||||
import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json';
|
||||
@@ -144,6 +148,7 @@ export const artifacts = {
|
||||
TransformERC20Feature: TransformERC20Feature as ContractArtifact,
|
||||
UniswapFeature: UniswapFeature as ContractArtifact,
|
||||
LibSignedCallData: LibSignedCallData as ContractArtifact,
|
||||
LibTokenSpender: LibTokenSpender as ContractArtifact,
|
||||
FixinCommon: FixinCommon as ContractArtifact,
|
||||
FixinEIP712: FixinEIP712 as ContractArtifact,
|
||||
FixinReentrancyGuard: FixinReentrancyGuard as ContractArtifact,
|
||||
@@ -173,11 +178,13 @@ export const artifacts = {
|
||||
MixinAdapterAddresses: MixinAdapterAddresses as ContractArtifact,
|
||||
MixinBalancer: MixinBalancer as ContractArtifact,
|
||||
MixinCurve: MixinCurve as ContractArtifact,
|
||||
MixinDodo: MixinDodo as ContractArtifact,
|
||||
MixinKyber: MixinKyber as ContractArtifact,
|
||||
MixinMStable: MixinMStable as ContractArtifact,
|
||||
MixinMooniswap: MixinMooniswap as ContractArtifact,
|
||||
MixinOasis: MixinOasis as ContractArtifact,
|
||||
MixinShell: MixinShell as ContractArtifact,
|
||||
MixinSushiswap: MixinSushiswap as ContractArtifact,
|
||||
MixinUniswap: MixinUniswap as ContractArtifact,
|
||||
MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
|
||||
MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
|
||||
@@ -193,6 +200,7 @@ export const artifacts = {
|
||||
TestFillQuoteTransformerHost: TestFillQuoteTransformerHost as ContractArtifact,
|
||||
TestFullMigration: TestFullMigration as ContractArtifact,
|
||||
TestInitialMigration: TestInitialMigration as ContractArtifact,
|
||||
TestLibTokenSpender: TestLibTokenSpender as ContractArtifact,
|
||||
TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact,
|
||||
TestMigrator: TestMigrator as ContractArtifact,
|
||||
TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact,
|
||||
|
@@ -2,12 +2,7 @@ import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contra
|
||||
import { blockchainTests, constants, expect, randomAddress, verifyEventsFromLogs } from '@0x/contracts-test-utils';
|
||||
import { BigNumber, OwnableRevertErrors, ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import {
|
||||
IOwnableFeatureContract,
|
||||
IZeroExContract,
|
||||
LiquidityProviderFeatureContract,
|
||||
TokenSpenderFeatureContract,
|
||||
} from '../../src/wrappers';
|
||||
import { IOwnableFeatureContract, IZeroExContract, LiquidityProviderFeatureContract } from '../../src/wrappers';
|
||||
import { artifacts } from '../artifacts';
|
||||
import { abis } from '../utils/abis';
|
||||
import { fullMigrateAsync } from '../utils/migration';
|
||||
@@ -23,16 +18,7 @@ blockchainTests('LiquidityProvider feature', env => {
|
||||
|
||||
before(async () => {
|
||||
[owner, taker] = await env.getAccountAddressesAsync();
|
||||
zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults, {
|
||||
tokenSpender: (await TokenSpenderFeatureContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestTokenSpender,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
)).address,
|
||||
});
|
||||
const tokenSpender = new TokenSpenderFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis);
|
||||
const allowanceTarget = await tokenSpender.getAllowanceTarget().callAsync();
|
||||
zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults, {});
|
||||
|
||||
token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
erc20Artifacts.DummyERC20Token,
|
||||
@@ -52,7 +38,7 @@ blockchainTests('LiquidityProvider feature', env => {
|
||||
artifacts,
|
||||
);
|
||||
await token
|
||||
.approve(allowanceTarget, constants.INITIAL_ERC20_ALLOWANCE)
|
||||
.approve(zeroEx.address, constants.INITIAL_ERC20_ALLOWANCE)
|
||||
.awaitTransactionSuccessAsync({ from: taker });
|
||||
|
||||
feature = new LiquidityProviderFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis);
|
||||
|
@@ -17,7 +17,6 @@ import { artifacts } from '../artifacts';
|
||||
import { abis } from '../utils/abis';
|
||||
import { fullMigrateAsync } from '../utils/migration';
|
||||
import {
|
||||
ITokenSpenderFeatureContract,
|
||||
TestMetaTransactionsTransformERC20FeatureContract,
|
||||
TestMetaTransactionsTransformERC20FeatureEvents,
|
||||
TestMintableERC20TokenContract,
|
||||
@@ -33,7 +32,6 @@ blockchainTests.resets('MetaTransactions feature', env => {
|
||||
let feature: MetaTransactionsFeatureContract;
|
||||
let feeToken: TestMintableERC20TokenContract;
|
||||
let transformERC20Feature: TestMetaTransactionsTransformERC20FeatureContract;
|
||||
let allowanceTarget: string;
|
||||
|
||||
const MAX_FEE_AMOUNT = new BigNumber('1e18');
|
||||
const TRANSFORM_ERC20_FAILING_VALUE = new BigNumber(666);
|
||||
@@ -64,14 +62,11 @@ blockchainTests.resets('MetaTransactions feature', env => {
|
||||
env.txDefaults,
|
||||
{},
|
||||
);
|
||||
allowanceTarget = await new ITokenSpenderFeatureContract(zeroEx.address, env.provider, env.txDefaults)
|
||||
.getAllowanceTarget()
|
||||
.callAsync();
|
||||
// Fund signers with fee tokens.
|
||||
await Promise.all(
|
||||
signers.map(async signer => {
|
||||
await feeToken.mint(signer, MAX_FEE_AMOUNT).awaitTransactionSuccessAsync();
|
||||
await feeToken.approve(allowanceTarget, MAX_FEE_AMOUNT).awaitTransactionSuccessAsync({ from: signer });
|
||||
await feeToken.approve(zeroEx.address, MAX_FEE_AMOUNT).awaitTransactionSuccessAsync({ from: signer });
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
@@ -20,7 +20,6 @@ import { abis } from '../utils/abis';
|
||||
import { fullMigrateAsync } from '../utils/migration';
|
||||
import {
|
||||
FlashWalletContract,
|
||||
ITokenSpenderFeatureContract,
|
||||
TestMintableERC20TokenContract,
|
||||
TestMintTokenERC20TransformerContract,
|
||||
TestMintTokenERC20TransformerEvents,
|
||||
@@ -42,7 +41,6 @@ blockchainTests.resets('TransformERC20 feature', env => {
|
||||
let zeroEx: IZeroExContract;
|
||||
let feature: TransformERC20FeatureContract;
|
||||
let wallet: FlashWalletContract;
|
||||
let allowanceTarget: string;
|
||||
|
||||
before(async () => {
|
||||
[owner, taker, sender, transformerDeployer] = await env.getAccountAddressesAsync();
|
||||
@@ -67,9 +65,6 @@ blockchainTests.resets('TransformERC20 feature', env => {
|
||||
abis,
|
||||
);
|
||||
wallet = new FlashWalletContract(await feature.getTransformWallet().callAsync(), env.provider, env.txDefaults);
|
||||
allowanceTarget = await new ITokenSpenderFeatureContract(zeroEx.address, env.provider, env.txDefaults)
|
||||
.getAllowanceTarget()
|
||||
.callAsync();
|
||||
await feature.setQuoteSigner(callDataSigner).awaitTransactionSuccessAsync({ from: owner });
|
||||
});
|
||||
|
||||
@@ -173,7 +168,7 @@ blockchainTests.resets('TransformERC20 feature', env => {
|
||||
},
|
||||
artifacts,
|
||||
);
|
||||
await inputToken.approve(allowanceTarget, MAX_UINT256).awaitTransactionSuccessAsync({ from: taker });
|
||||
await inputToken.approve(zeroEx.address, MAX_UINT256).awaitTransactionSuccessAsync({ from: taker });
|
||||
});
|
||||
|
||||
interface Transformation {
|
||||
|
210
contracts/zero-ex/test/lib_token_spender_test.ts
Normal file
210
contracts/zero-ex/test/lib_token_spender_test.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import {
|
||||
blockchainTests,
|
||||
expect,
|
||||
getRandomInteger,
|
||||
randomAddress,
|
||||
verifyEventsFromLogs,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { BigNumber, hexUtils, StringRevertError, ZeroExRevertErrors } from '@0x/utils';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import {
|
||||
TestLibTokenSpenderContract,
|
||||
TestLibTokenSpenderEvents,
|
||||
TestTokenSpenderERC20TokenContract,
|
||||
TestTokenSpenderERC20TokenEvents,
|
||||
} from './wrappers';
|
||||
|
||||
blockchainTests.resets('LibTokenSpender library', env => {
|
||||
let tokenSpender: TestLibTokenSpenderContract;
|
||||
let token: TestTokenSpenderERC20TokenContract;
|
||||
|
||||
before(async () => {
|
||||
tokenSpender = await TestLibTokenSpenderContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestLibTokenSpender,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
token = await TestTokenSpenderERC20TokenContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestTokenSpenderERC20Token,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
artifacts,
|
||||
);
|
||||
});
|
||||
|
||||
describe('spendERC20Tokens()', () => {
|
||||
const EMPTY_RETURN_AMOUNT = 1337;
|
||||
const FALSE_RETURN_AMOUNT = 1338;
|
||||
const REVERT_RETURN_AMOUNT = 1339;
|
||||
const TRIGGER_FALLBACK_SUCCESS_AMOUNT = 1340;
|
||||
const EXTRA_RETURN_TRUE_AMOUNT = 1341;
|
||||
const EXTRA_RETURN_FALSE_AMOUNT = 1342;
|
||||
|
||||
it('spendERC20Tokens() successfully calls compliant ERC20 token', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(123456);
|
||||
const receipt = await tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
verifyEventsFromLogs(
|
||||
receipt.logs,
|
||||
[
|
||||
{
|
||||
sender: tokenSpender.address,
|
||||
from: tokenFrom,
|
||||
to: tokenTo,
|
||||
amount: tokenAmount,
|
||||
},
|
||||
],
|
||||
TestTokenSpenderERC20TokenEvents.TransferFromCalled,
|
||||
);
|
||||
});
|
||||
|
||||
it('spendERC20Tokens() successfully calls non-compliant ERC20 token', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(EMPTY_RETURN_AMOUNT);
|
||||
const receipt = await tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
verifyEventsFromLogs(
|
||||
receipt.logs,
|
||||
[
|
||||
{
|
||||
sender: tokenSpender.address,
|
||||
from: tokenFrom,
|
||||
to: tokenTo,
|
||||
amount: tokenAmount,
|
||||
},
|
||||
],
|
||||
TestTokenSpenderERC20TokenEvents.TransferFromCalled,
|
||||
);
|
||||
});
|
||||
|
||||
it('spendERC20Tokens() reverts if ERC20 token reverts', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(REVERT_RETURN_AMOUNT);
|
||||
const tx = tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const expectedError = new ZeroExRevertErrors.Spender.SpenderERC20TransferFromFailedError(
|
||||
token.address,
|
||||
tokenFrom,
|
||||
tokenTo,
|
||||
tokenAmount,
|
||||
new StringRevertError('TestTokenSpenderERC20Token/Revert').encode(),
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('spendERC20Tokens() reverts if ERC20 token returns false', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(FALSE_RETURN_AMOUNT);
|
||||
const tx = tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
return expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.Spender.SpenderERC20TransferFromFailedError(
|
||||
token.address,
|
||||
tokenFrom,
|
||||
tokenTo,
|
||||
tokenAmount,
|
||||
hexUtils.leftPad(0),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('spendERC20Tokens() falls back successfully to TokenSpender._spendERC20Tokens()', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(TRIGGER_FALLBACK_SUCCESS_AMOUNT);
|
||||
const receipt = await tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
verifyEventsFromLogs(
|
||||
receipt.logs,
|
||||
[
|
||||
{
|
||||
token: token.address,
|
||||
owner: tokenFrom,
|
||||
to: tokenTo,
|
||||
amount: tokenAmount,
|
||||
},
|
||||
],
|
||||
TestLibTokenSpenderEvents.FallbackCalled,
|
||||
);
|
||||
});
|
||||
|
||||
it('spendERC20Tokens() allows extra data after true', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(EXTRA_RETURN_TRUE_AMOUNT);
|
||||
|
||||
const receipt = await tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
verifyEventsFromLogs(
|
||||
receipt.logs,
|
||||
[
|
||||
{
|
||||
sender: tokenSpender.address,
|
||||
from: tokenFrom,
|
||||
to: tokenTo,
|
||||
amount: tokenAmount,
|
||||
},
|
||||
],
|
||||
TestTokenSpenderERC20TokenEvents.TransferFromCalled,
|
||||
);
|
||||
});
|
||||
|
||||
it("spendERC20Tokens() reverts when there's extra data after false", async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(EXTRA_RETURN_FALSE_AMOUNT);
|
||||
|
||||
const tx = tokenSpender
|
||||
.spendERC20Tokens(token.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
return expect(tx).to.revertWith(
|
||||
new ZeroExRevertErrors.Spender.SpenderERC20TransferFromFailedError(
|
||||
token.address,
|
||||
tokenFrom,
|
||||
tokenTo,
|
||||
tokenAmount,
|
||||
hexUtils.leftPad(EXTRA_RETURN_FALSE_AMOUNT, 64),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('spendERC20Tokens() cannot call self', async () => {
|
||||
const tokenFrom = randomAddress();
|
||||
const tokenTo = randomAddress();
|
||||
const tokenAmount = new BigNumber(123456);
|
||||
|
||||
const tx = tokenSpender
|
||||
.spendERC20Tokens(tokenSpender.address, tokenFrom, tokenTo, tokenAmount)
|
||||
.awaitTransactionSuccessAsync();
|
||||
return expect(tx).to.revertWith('LibTokenSpender/CANNOT_INVOKE_SELF');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSpendableERC20BalanceOf()', () => {
|
||||
it("returns the minimum of the owner's balance and allowance", async () => {
|
||||
const balance = getRandomInteger(1, '1e18');
|
||||
const allowance = getRandomInteger(1, '1e18');
|
||||
const tokenOwner = randomAddress();
|
||||
await token
|
||||
.setBalanceAndAllowanceOf(tokenOwner, balance, tokenSpender.address, allowance)
|
||||
.awaitTransactionSuccessAsync();
|
||||
const spendableBalance = await tokenSpender
|
||||
.getSpendableERC20BalanceOf(token.address, tokenOwner)
|
||||
.callAsync();
|
||||
expect(spendableBalance).to.bignumber.eq(BigNumber.min(balance, allowance));
|
||||
});
|
||||
});
|
||||
});
|
@@ -65,10 +65,13 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
||||
mooniswapBridge: NULL_ADDRESS,
|
||||
mStableBridge: NULL_ADDRESS,
|
||||
oasisBridge: NULL_ADDRESS,
|
||||
sushiswapBridge: NULL_ADDRESS,
|
||||
swerveBridge: NULL_ADDRESS,
|
||||
uniswapBridge: NULL_ADDRESS,
|
||||
uniswapV2Bridge: NULL_ADDRESS,
|
||||
kyberNetworkProxy: NULL_ADDRESS,
|
||||
oasis: NULL_ADDRESS,
|
||||
sushiswapRouter: NULL_ADDRESS,
|
||||
uniswapV2Router: NULL_ADDRESS,
|
||||
uniswapExchangeFactory: NULL_ADDRESS,
|
||||
mStable: NULL_ADDRESS,
|
||||
@@ -76,6 +79,9 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
||||
shellBridge: NULL_ADDRESS,
|
||||
shell: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
dodoHelper: NULL_ADDRESS,
|
||||
snowSwapBridge: NULL_ADDRESS,
|
||||
},
|
||||
);
|
||||
transformer = await FillQuoteTransformerContract.deployFrom0xArtifactAsync(
|
||||
|
@@ -52,6 +52,7 @@ export * from '../test/generated-wrappers/lib_simple_function_registry_rich_erro
|
||||
export * from '../test/generated-wrappers/lib_simple_function_registry_storage';
|
||||
export * from '../test/generated-wrappers/lib_spender_rich_errors';
|
||||
export * from '../test/generated-wrappers/lib_storage';
|
||||
export * from '../test/generated-wrappers/lib_token_spender';
|
||||
export * from '../test/generated-wrappers/lib_token_spender_storage';
|
||||
export * from '../test/generated-wrappers/lib_transform_erc20_rich_errors';
|
||||
export * from '../test/generated-wrappers/lib_transform_erc20_storage';
|
||||
@@ -62,11 +63,13 @@ export * from '../test/generated-wrappers/meta_transactions_feature';
|
||||
export * from '../test/generated-wrappers/mixin_adapter_addresses';
|
||||
export * from '../test/generated-wrappers/mixin_balancer';
|
||||
export * from '../test/generated-wrappers/mixin_curve';
|
||||
export * from '../test/generated-wrappers/mixin_dodo';
|
||||
export * from '../test/generated-wrappers/mixin_kyber';
|
||||
export * from '../test/generated-wrappers/mixin_m_stable';
|
||||
export * from '../test/generated-wrappers/mixin_mooniswap';
|
||||
export * from '../test/generated-wrappers/mixin_oasis';
|
||||
export * from '../test/generated-wrappers/mixin_shell';
|
||||
export * from '../test/generated-wrappers/mixin_sushiswap';
|
||||
export * from '../test/generated-wrappers/mixin_uniswap';
|
||||
export * from '../test/generated-wrappers/mixin_uniswap_v2';
|
||||
export * from '../test/generated-wrappers/mixin_zero_ex_bridge';
|
||||
@@ -82,6 +85,7 @@ export * from '../test/generated-wrappers/test_fill_quote_transformer_exchange';
|
||||
export * from '../test/generated-wrappers/test_fill_quote_transformer_host';
|
||||
export * from '../test/generated-wrappers/test_full_migration';
|
||||
export * from '../test/generated-wrappers/test_initial_migration';
|
||||
export * from '../test/generated-wrappers/test_lib_token_spender';
|
||||
export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature';
|
||||
export * from '../test/generated-wrappers/test_migrator';
|
||||
export * from '../test/generated-wrappers/test_mint_token_erc20_transformer';
|
||||
|
@@ -76,6 +76,7 @@
|
||||
"test/generated-artifacts/LibSimpleFunctionRegistryStorage.json",
|
||||
"test/generated-artifacts/LibSpenderRichErrors.json",
|
||||
"test/generated-artifacts/LibStorage.json",
|
||||
"test/generated-artifacts/LibTokenSpender.json",
|
||||
"test/generated-artifacts/LibTokenSpenderStorage.json",
|
||||
"test/generated-artifacts/LibTransformERC20RichErrors.json",
|
||||
"test/generated-artifacts/LibTransformERC20Storage.json",
|
||||
@@ -86,11 +87,13 @@
|
||||
"test/generated-artifacts/MixinAdapterAddresses.json",
|
||||
"test/generated-artifacts/MixinBalancer.json",
|
||||
"test/generated-artifacts/MixinCurve.json",
|
||||
"test/generated-artifacts/MixinDodo.json",
|
||||
"test/generated-artifacts/MixinKyber.json",
|
||||
"test/generated-artifacts/MixinMStable.json",
|
||||
"test/generated-artifacts/MixinMooniswap.json",
|
||||
"test/generated-artifacts/MixinOasis.json",
|
||||
"test/generated-artifacts/MixinShell.json",
|
||||
"test/generated-artifacts/MixinSushiswap.json",
|
||||
"test/generated-artifacts/MixinUniswap.json",
|
||||
"test/generated-artifacts/MixinUniswapV2.json",
|
||||
"test/generated-artifacts/MixinZeroExBridge.json",
|
||||
@@ -106,6 +109,7 @@
|
||||
"test/generated-artifacts/TestFillQuoteTransformerHost.json",
|
||||
"test/generated-artifacts/TestFullMigration.json",
|
||||
"test/generated-artifacts/TestInitialMigration.json",
|
||||
"test/generated-artifacts/TestLibTokenSpender.json",
|
||||
"test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json",
|
||||
"test/generated-artifacts/TestMigrator.json",
|
||||
"test/generated-artifacts/TestMintTokenERC20Transformer.json",
|
||||
|
@@ -20,8 +20,10 @@
|
||||
"test:publish:circleci": "yarn npm-cli-login -u test -p test -e test@example.com -r http://localhost:4873 && IS_LOCAL_PUBLISH=true run-s script:publish test:installation:local",
|
||||
"run:publish": "run-s install:all script:prepublish_checks rebuild script:publish",
|
||||
"run:publish:local": "IS_LOCAL_PUBLISH=true yarn run:publish",
|
||||
"run:publish:gha": "run-s build script:publish:gha",
|
||||
"script:prepublish_checks": "node ./node_modules/@0x/monorepo-scripts/lib/prepublish_checks.js",
|
||||
"script:publish": "node ./node_modules/@0x/monorepo-scripts/lib/publish.js --repo protocol",
|
||||
"script:publish:gha": "node ./node_modules/@0x/monorepo-scripts/lib/publish.js --repo protocol --auto-commit --no-upload-docs --yes",
|
||||
"install:all": "yarn install",
|
||||
"wsrun": "wsrun",
|
||||
"lerna": "lerna",
|
||||
@@ -64,7 +66,7 @@
|
||||
"ignoreDependencyVersionsForPackage": "contract-wrappers"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/monorepo-scripts": "^2.0.3",
|
||||
"@0x/monorepo-scripts": "^2.0.4",
|
||||
"@0x-lerna-fork/lerna": "3.16.10",
|
||||
"@0xproject/npm-cli-login": "^0.0.11",
|
||||
"async-child-process": "^1.1.1",
|
||||
|
@@ -1,4 +1,27 @@
|
||||
[
|
||||
{
|
||||
"version": "4.8.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Moved Bridge addresses into Asset-swapper",
|
||||
"pr": 4
|
||||
},
|
||||
{
|
||||
"note": "Updated Sampler to Solidity 0.6",
|
||||
"pr": 4
|
||||
}
|
||||
],
|
||||
"timestamp": 1603833198
|
||||
},
|
||||
{
|
||||
"timestamp": 1603487270,
|
||||
"version": "4.7.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.7.0",
|
||||
"changes": [
|
||||
@@ -163,8 +186,12 @@
|
||||
"pr": 2731
|
||||
},
|
||||
{
|
||||
"note": "Support DODO Trade Allowed parameter to automatically disable the pool",
|
||||
"note": "Support `DODO` Trade Allowed parameter to automatically disable the pool",
|
||||
"pr": 2732
|
||||
},
|
||||
{
|
||||
"note": "Added `SwerveBridge` and `SnowSwapBridge` deployed addresses",
|
||||
"pr": 7
|
||||
}
|
||||
],
|
||||
"timestamp": 1603265572
|
||||
|
@@ -5,6 +5,15 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.8.0 - _October 27, 2020_
|
||||
|
||||
* Moved Bridge addresses into Asset-swapper (#4)
|
||||
* Updated Sampler to Solidity 0.6 (#4)
|
||||
|
||||
## v4.7.1 - _October 23, 2020_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.7.0 - _October 21, 2020_
|
||||
|
||||
* Return quoteReport from SwapQuoter functions (#2627)
|
||||
@@ -47,7 +56,8 @@ CHANGELOG
|
||||
* Added `DODO` (#2701)
|
||||
* Fix for some edge cases with `includedSources` and `MultiHop` (#2730)
|
||||
* Introduced `excludedFeeSources` to disable sources when determining the price of an asset in ETH (#2731)
|
||||
* Support DODO Trade Allowed parameter to automatically disable the pool (#2732)
|
||||
* Support `DODO` Trade Allowed parameter to automatically disable the pool (#2732)
|
||||
* Added `SwerveBridge` and `SnowSwapBridge` deployed addresses (#7)
|
||||
|
||||
## v4.6.0 - _July 15, 2020_
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
|
||||
|
||||
|
||||
contract ApproximateBuys {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/IBalancer.sol";
|
||||
@@ -78,24 +78,24 @@ contract BalancerSampler {
|
||||
if (takerTokenAmounts[i] > _bmul(poolState.takerTokenBalance, MAX_IN_RATIO)) {
|
||||
break;
|
||||
}
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
poolAddress.staticcall.gas(BALANCER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
pool.calcOutGivenIn.selector,
|
||||
try
|
||||
pool.calcOutGivenIn
|
||||
{gas: BALANCER_CALL_GAS}
|
||||
(
|
||||
poolState.takerTokenBalance,
|
||||
poolState.takerTokenWeight,
|
||||
poolState.makerTokenBalance,
|
||||
poolState.makerTokenWeight,
|
||||
takerTokenAmounts[i],
|
||||
poolState.swapFee
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
buyAmount = abi.decode(resultData, (uint256));
|
||||
} else {
|
||||
)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
makerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,24 +136,24 @@ contract BalancerSampler {
|
||||
if (makerTokenAmounts[i] > _bmul(poolState.makerTokenBalance, MAX_OUT_RATIO)) {
|
||||
break;
|
||||
}
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
poolAddress.staticcall.gas(BALANCER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
pool.calcInGivenOut.selector,
|
||||
try
|
||||
pool.calcInGivenOut
|
||||
{gas: BALANCER_CALL_GAS}
|
||||
(
|
||||
poolState.takerTokenBalance,
|
||||
poolState.takerTokenWeight,
|
||||
poolState.makerTokenBalance,
|
||||
poolState.makerTokenWeight,
|
||||
makerTokenAmounts[i],
|
||||
poolState.swapFee
|
||||
));
|
||||
uint256 sellAmount = 0;
|
||||
if (didSucceed) {
|
||||
sellAmount = abi.decode(resultData, (uint256));
|
||||
} else {
|
||||
)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
takerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
takerTokenAmounts[i] = sellAmount;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/ICurve.sol";
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
|
||||
@@ -50,6 +50,8 @@ contract DODOSampler is
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return sellBase whether the bridge needs to sell the base token
|
||||
/// @return pool the DODO pool address
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromDODO(
|
||||
@@ -104,6 +106,8 @@ contract DODOSampler is
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token sell amount for each sample.
|
||||
/// @return sellBase whether the bridge needs to sell the base token
|
||||
/// @return pool the DODO pool address
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function sampleBuysFromDODO(
|
||||
@@ -167,32 +171,34 @@ contract DODOSampler is
|
||||
(address, address, address)
|
||||
);
|
||||
|
||||
bool didSucceed;
|
||||
bytes memory resultData;
|
||||
// We will get called to sell both the taker token and also to sell the maker token
|
||||
if (takerToken == baseToken) {
|
||||
// If base token then use the original query on the pool
|
||||
(didSucceed, resultData) =
|
||||
pool.staticcall.gas(DODO_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IDODO(0).querySellBaseToken.selector,
|
||||
sellAmount
|
||||
));
|
||||
try
|
||||
IDODO(pool).querySellBaseToken
|
||||
{gas: DODO_CALL_GAS}
|
||||
(sellAmount)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
return amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// If quote token then use helper, this is less accurate
|
||||
(didSucceed, resultData) =
|
||||
_getDODOHelperAddress().staticcall.gas(DODO_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IDODOHelper(0).querySellQuoteToken.selector,
|
||||
pool,
|
||||
sellAmount
|
||||
));
|
||||
try
|
||||
IDODOHelper(_getDODOHelperAddress()).querySellQuoteToken
|
||||
{gas: DODO_CALL_GAS}
|
||||
(pool, sellAmount)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
return amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!didSucceed) {
|
||||
return 0;
|
||||
}
|
||||
// solhint-disable-next-line indent
|
||||
return abi.decode(resultData, (uint256));
|
||||
}
|
||||
|
||||
}
|
||||
|
340
packages/asset-swapper/contracts/src/DeploymentConstants.sol
Normal file
340
packages/asset-swapper/contracts/src/DeploymentConstants.sol
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
|
||||
|
||||
contract DeploymentConstants {
|
||||
|
||||
// solhint-disable separate-by-one-line-in-contract
|
||||
|
||||
// Mainnet addresses ///////////////////////////////////////////////////////
|
||||
/// @dev Mainnet address of the WETH contract.
|
||||
address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
/// @dev Mainnet address of the KyberNetworkProxy contract.
|
||||
address constant private KYBER_NETWORK_PROXY_ADDRESS = 0x9AAb3f75489902f3a48495025729a0AF77d4b11e;
|
||||
/// @dev Mainnet address of the KyberHintHandler contract.
|
||||
address constant private KYBER_HINT_HANDLER_ADDRESS = 0xa1C0Fa73c39CFBcC11ec9Eb1Afc665aba9996E2C;
|
||||
/// @dev Mainnet address of the `UniswapExchangeFactory` contract.
|
||||
address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||
/// @dev Mainnet address of the `UniswapV2Router01` contract.
|
||||
address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
|
||||
/// @dev Mainnet address of the Eth2Dai `MatchingMarket` contract.
|
||||
address constant private ETH2DAI_ADDRESS = 0x794e6e91555438aFc3ccF1c5076A74F42133d08D;
|
||||
/// @dev Mainnet address of the `ERC20BridgeProxy` contract
|
||||
address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0x8ED95d1746bf1E4dAb58d8ED4724f1Ef95B20Db0;
|
||||
///@dev Mainnet address of the `Dai` (multi-collateral) contract
|
||||
address constant private DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
|
||||
/// @dev Mainnet address of the `Chai` contract
|
||||
address constant private CHAI_ADDRESS = 0x06AF07097C9Eeb7fD685c692751D5C66dB49c215;
|
||||
/// @dev Mainnet address of the 0x DevUtils contract.
|
||||
address constant private DEV_UTILS_ADDRESS = 0x74134CF88b21383713E096a5ecF59e297dc7f547;
|
||||
/// @dev Kyber ETH pseudo-address.
|
||||
address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
/// @dev Mainnet address of the dYdX contract.
|
||||
address constant private DYDX_ADDRESS = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e;
|
||||
/// @dev Mainnet address of the GST2 contract
|
||||
address constant private GST_ADDRESS = 0x0000000000b3F879cb30FE243b4Dfee438691c04;
|
||||
/// @dev Mainnet address of the GST Collector
|
||||
address constant private GST_COLLECTOR_ADDRESS = 0x000000D3b08566BE75A6DB803C03C85C0c1c5B96;
|
||||
/// @dev Mainnet address of the mStable mUSD contract.
|
||||
address constant private MUSD_ADDRESS = 0xe2f2a5C287993345a840Db3B0845fbC70f5935a5;
|
||||
/// @dev Mainnet address of the Mooniswap Registry contract
|
||||
address constant private MOONISWAP_REGISTRY = 0x71CD6666064C3A1354a3B4dca5fA1E2D3ee7D303;
|
||||
/// @dev Mainnet address of the Shell contract
|
||||
address constant private SHELL_CONTRACT = 0x2E703D658f8dd21709a7B458967aB4081F8D3d05;
|
||||
/// @dev Mainnet address of the DODO Registry (ZOO) contract
|
||||
address constant private DODO_REGISTRY = 0x3A97247DF274a17C59A3bd12735ea3FcDFb49950;
|
||||
/// @dev Mainnet address of the DODO Helper contract
|
||||
address constant private DODO_HELPER = 0x533dA777aeDCE766CEAe696bf90f8541A4bA80Eb;
|
||||
|
||||
// // Ropsten addresses ///////////////////////////////////////////////////////
|
||||
// /// @dev Mainnet address of the WETH contract.
|
||||
// address constant private WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
|
||||
// /// @dev Mainnet address of the KyberNetworkProxy contract.
|
||||
// address constant private KYBER_NETWORK_PROXY_ADDRESS = 0xd719c34261e099Fdb33030ac8909d5788D3039C4;
|
||||
// /// @dev Mainnet address of the `UniswapExchangeFactory` contract.
|
||||
// address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0x9c83dCE8CA20E9aAF9D3efc003b2ea62aBC08351;
|
||||
// /// @dev Mainnet address of the `UniswapV2Router01` contract.
|
||||
// address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
|
||||
// /// @dev Mainnet address of the Eth2Dai `MatchingMarket` contract.
|
||||
// address constant private ETH2DAI_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the `ERC20BridgeProxy` contract
|
||||
// address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0xb344afeD348de15eb4a9e180205A2B0739628339;
|
||||
// ///@dev Mainnet address of the `Dai` (multi-collateral) contract
|
||||
// address constant private DAI_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the `Chai` contract
|
||||
// address constant private CHAI_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the 0x DevUtils contract.
|
||||
// address constant private DEV_UTILS_ADDRESS = 0xC812AF3f3fBC62F76ea4262576EC0f49dB8B7f1c;
|
||||
// /// @dev Kyber ETH pseudo-address.
|
||||
// address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
// /// @dev Mainnet address of the dYdX contract.
|
||||
// address constant private DYDX_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the GST2 contract
|
||||
// address constant private GST_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the GST Collector
|
||||
// address constant private GST_COLLECTOR_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the mStable mUSD contract.
|
||||
// address constant private MUSD_ADDRESS = 0x4E1000616990D83e56f4b5fC6CC8602DcfD20459;
|
||||
|
||||
// // Rinkeby addresses ///////////////////////////////////////////////////////
|
||||
// /// @dev Mainnet address of the WETH contract.
|
||||
// address constant private WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
|
||||
// /// @dev Mainnet address of the KyberNetworkProxy contract.
|
||||
// address constant private KYBER_NETWORK_PROXY_ADDRESS = 0x0d5371e5EE23dec7DF251A8957279629aa79E9C5;
|
||||
// /// @dev Mainnet address of the `UniswapExchangeFactory` contract.
|
||||
// address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xf5D915570BC477f9B8D6C0E980aA81757A3AaC36;
|
||||
// /// @dev Mainnet address of the `UniswapV2Router01` contract.
|
||||
// address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
|
||||
// /// @dev Mainnet address of the Eth2Dai `MatchingMarket` contract.
|
||||
// address constant private ETH2DAI_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the `ERC20BridgeProxy` contract
|
||||
// address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0xA2AA4bEFED748Fba27a3bE7Dfd2C4b2c6DB1F49B;
|
||||
// ///@dev Mainnet address of the `Dai` (multi-collateral) contract
|
||||
// address constant private DAI_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the `Chai` contract
|
||||
// address constant private CHAI_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the 0x DevUtils contract.
|
||||
// address constant private DEV_UTILS_ADDRESS = 0x46B5BC959e8A754c0256FFF73bF34A52Ad5CdfA9;
|
||||
// /// @dev Kyber ETH pseudo-address.
|
||||
// address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
// /// @dev Mainnet address of the dYdX contract.
|
||||
// address constant private DYDX_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the GST2 contract
|
||||
// address constant private GST_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the GST Collector
|
||||
// address constant private GST_COLLECTOR_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the mStable mUSD contract.
|
||||
// address constant private MUSD_ADDRESS = address(0);
|
||||
|
||||
// // Kovan addresses /////////////////////////////////////////////////////////
|
||||
// /// @dev Kovan address of the WETH contract.
|
||||
// address constant private WETH_ADDRESS = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
|
||||
// /// @dev Kovan address of the KyberNetworkProxy contract.
|
||||
// address constant private KYBER_NETWORK_PROXY_ADDRESS = 0x692f391bCc85cefCe8C237C01e1f636BbD70EA4D;
|
||||
// /// @dev Kovan address of the `UniswapExchangeFactory` contract.
|
||||
// address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xD3E51Ef092B2845f10401a0159B2B96e8B6c3D30;
|
||||
// /// @dev Kovan address of the `UniswapV2Router01` contract.
|
||||
// address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
|
||||
// /// @dev Kovan address of the Eth2Dai `MatchingMarket` contract.
|
||||
// address constant private ETH2DAI_ADDRESS = 0xe325acB9765b02b8b418199bf9650972299235F4;
|
||||
// /// @dev Kovan address of the `ERC20BridgeProxy` contract
|
||||
// address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0x3577552C1Fb7A44aD76BeEB7aB53251668A21F8D;
|
||||
// /// @dev Kovan address of the `Chai` contract
|
||||
// address constant private CHAI_ADDRESS = address(0);
|
||||
// /// @dev Kovan address of the `Dai` (multi-collateral) contract
|
||||
// address constant private DAI_ADDRESS = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;
|
||||
// /// @dev Kovan address of the 0x DevUtils contract.
|
||||
// address constant private DEV_UTILS_ADDRESS = 0x9402639A828BdF4E9e4103ac3B69E1a6E522eB59;
|
||||
// /// @dev Kyber ETH pseudo-address.
|
||||
// address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
// /// @dev Kovan address of the dYdX contract.
|
||||
// address constant private DYDX_ADDRESS = address(0);
|
||||
// /// @dev Kovan address of the GST2 contract
|
||||
// address constant private GST_ADDRESS = address(0);
|
||||
// /// @dev Kovan address of the GST Collector
|
||||
// address constant private GST_COLLECTOR_ADDRESS = address(0);
|
||||
// /// @dev Mainnet address of the mStable mUSD contract.
|
||||
// address constant private MUSD_ADDRESS = address(0);
|
||||
|
||||
/// @dev Overridable way to get the `KyberNetworkProxy` address.
|
||||
/// @return kyberAddress The `IKyberNetworkProxy` address.
|
||||
function _getKyberNetworkProxyAddress()
|
||||
virtual
|
||||
internal
|
||||
view
|
||||
returns (address kyberAddress)
|
||||
{
|
||||
return KYBER_NETWORK_PROXY_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev Overridable way to get the `KyberHintHandler` address.
|
||||
/// @return hintHandlerAddress The `IKyberHintHandler` address.
|
||||
function _getKyberHintHandlerAddress()
|
||||
virtual
|
||||
internal
|
||||
view
|
||||
returns (address hintHandlerAddress)
|
||||
{
|
||||
return KYBER_HINT_HANDLER_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev Overridable way to get the WETH address.
|
||||
/// @return wethAddress The WETH address.
|
||||
function _getWethAddress()
|
||||
internal
|
||||
view
|
||||
returns (address wethAddress)
|
||||
{
|
||||
return WETH_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev Overridable way to get the `UniswapExchangeFactory` address.
|
||||
/// @return uniswapAddress The `UniswapExchangeFactory` address.
|
||||
function _getUniswapExchangeFactoryAddress()
|
||||
virtual
|
||||
internal
|
||||
view
|
||||
returns (address uniswapAddress)
|
||||
{
|
||||
return UNISWAP_EXCHANGE_FACTORY_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev Overridable way to get the `UniswapV2Router01` address.
|
||||
/// @return uniswapRouterAddress The `UniswapV2Router01` address.
|
||||
function _getUniswapV2Router01Address()
|
||||
virtual
|
||||
internal
|
||||
view
|
||||
returns (address uniswapRouterAddress)
|
||||
{
|
||||
return UNISWAP_V2_ROUTER_01_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Eth2Dai `MatchingMarket` contract.
|
||||
/// @return eth2daiAddress The Eth2Dai `MatchingMarket` contract.
|
||||
function _getEth2DaiAddress()
|
||||
virtual
|
||||
internal
|
||||
view
|
||||
returns (address eth2daiAddress)
|
||||
{
|
||||
return ETH2DAI_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the `ERC20BridgeProxy` contract.
|
||||
/// @return erc20BridgeProxyAddress The `ERC20BridgeProxy` contract.
|
||||
function _getERC20BridgeProxyAddress()
|
||||
internal
|
||||
view
|
||||
returns (address erc20BridgeProxyAddress)
|
||||
{
|
||||
return ERC20_BRIDGE_PROXY_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the `Dai` contract.
|
||||
/// @return daiAddress The `Dai` contract.
|
||||
function _getDaiAddress()
|
||||
internal
|
||||
view
|
||||
returns (address daiAddress)
|
||||
{
|
||||
return DAI_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the `Chai` contract.
|
||||
/// @return chaiAddress The `Chai` contract.
|
||||
function _getChaiAddress()
|
||||
internal
|
||||
view
|
||||
returns (address chaiAddress)
|
||||
{
|
||||
return CHAI_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the 0x `DevUtils` contract address.
|
||||
/// @return devUtils The 0x `DevUtils` contract address.
|
||||
function _getDevUtilsAddress()
|
||||
internal
|
||||
view
|
||||
returns (address devUtils)
|
||||
{
|
||||
return DEV_UTILS_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev Overridable way to get the DyDx contract.
|
||||
/// @return dydxAddress exchange The DyDx exchange contract.
|
||||
function _getDydxAddress()
|
||||
internal
|
||||
view
|
||||
returns (address dydxAddress)
|
||||
{
|
||||
return DYDX_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the GST2 contract address.
|
||||
/// @return gst The GST contract.
|
||||
function _getGstAddress()
|
||||
internal
|
||||
view
|
||||
returns (address gst)
|
||||
{
|
||||
return GST_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the GST Collector address.
|
||||
/// @return collector The GST collector address.
|
||||
function _getGstCollectorAddress()
|
||||
internal
|
||||
view
|
||||
returns (address collector)
|
||||
{
|
||||
return GST_COLLECTOR_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the mStable mUSD address.
|
||||
/// @return musd The mStable mUSD address.
|
||||
function _getMUsdAddress()
|
||||
internal
|
||||
view
|
||||
returns (address musd)
|
||||
{
|
||||
return MUSD_ADDRESS;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Mooniswap registry address.
|
||||
/// @return registry The Mooniswap registry address.
|
||||
function _getMooniswapAddress()
|
||||
internal
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return MOONISWAP_REGISTRY;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Shell contract address.
|
||||
/// @return registry The Shell contract address.
|
||||
function _getShellAddress()
|
||||
internal
|
||||
view
|
||||
returns (address registry)
|
||||
{
|
||||
return SHELL_CONTRACT;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the DODO Registry contract address.
|
||||
/// @return registry The DODO Registry contract address.
|
||||
function _getDODORegistryAddress()
|
||||
internal
|
||||
view
|
||||
returns (address registry)
|
||||
{
|
||||
return DODO_REGISTRY;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the DODO Helper contract address.
|
||||
/// @return registry The DODO Helper contract address.
|
||||
function _getDODOHelperAddress()
|
||||
internal
|
||||
view
|
||||
returns (address registry)
|
||||
{
|
||||
return DODO_HELPER;
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./BalancerSampler.sol";
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IEth2Dai.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
|
||||
@@ -50,23 +50,17 @@ contract Eth2DaiSampler is
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getEth2DaiAddress().staticcall.gas(ETH2DAI_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IEth2Dai(0).getBuyAmount.selector,
|
||||
makerToken,
|
||||
takerToken,
|
||||
takerTokenAmounts[i]
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
buyAmount = abi.decode(resultData, (uint256));
|
||||
}
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (buyAmount == 0) {
|
||||
try
|
||||
IEth2Dai(_getEth2DaiAddress()).getBuyAmount
|
||||
{gas: ETH2DAI_CALL_GAS}
|
||||
(makerToken, takerToken, takerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
{
|
||||
makerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,23 +83,17 @@ contract Eth2DaiSampler is
|
||||
uint256 numSamples = makerTokenAmounts.length;
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getEth2DaiAddress().staticcall.gas(ETH2DAI_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IEth2Dai(0).getPayAmount.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
makerTokenAmounts[i]
|
||||
));
|
||||
uint256 sellAmount = 0;
|
||||
if (didSucceed) {
|
||||
sellAmount = abi.decode(resultData, (uint256));
|
||||
}
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (sellAmount == 0) {
|
||||
try
|
||||
IEth2Dai(_getEth2DaiAddress()).getPayAmount
|
||||
{gas: ETH2DAI_CALL_GAS}
|
||||
(takerToken, makerToken, makerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
{
|
||||
takerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
takerTokenAmounts[i] = sellAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IKyberNetwork.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
@@ -109,52 +109,66 @@ contract KyberSampler is
|
||||
// All other reserves should be ignored with this hint
|
||||
bytes32[] memory selectedReserves = new bytes32[](1);
|
||||
selectedReserves[0] = reserveId;
|
||||
uint256[] memory emptySplits = new uint256[](0);
|
||||
|
||||
bool didSucceed;
|
||||
bytes memory resultData;
|
||||
if (takerToken == _getWethAddress()) {
|
||||
// ETH to Token
|
||||
(didSucceed, resultData) =
|
||||
address(kyberHint).staticcall.gas(KYBER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IKyberHintHandler(0).buildEthToTokenHint.selector,
|
||||
try
|
||||
kyberHint.buildEthToTokenHint
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
makerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
new uint256[](0)));
|
||||
emptySplits
|
||||
)
|
||||
returns (bytes memory result)
|
||||
{
|
||||
return result;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
}
|
||||
} else if (makerToken == _getWethAddress()) {
|
||||
// Token to ETH
|
||||
(didSucceed, resultData) =
|
||||
address(kyberHint).staticcall.gas(KYBER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IKyberHintHandler(0).buildTokenToEthHint.selector,
|
||||
try
|
||||
kyberHint.buildTokenToEthHint
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
takerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
new uint256[](0)));
|
||||
emptySplits
|
||||
)
|
||||
returns (bytes memory result)
|
||||
{
|
||||
return result;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
}
|
||||
|
||||
} else {
|
||||
// Token to Token
|
||||
// We use the same reserve both ways
|
||||
(didSucceed, resultData) =
|
||||
address(kyberHint).staticcall.gas(KYBER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IKyberHintHandler(0).buildTokenToTokenHint.selector,
|
||||
try
|
||||
kyberHint.buildTokenToTokenHint
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
takerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
new uint256[](0),
|
||||
emptySplits,
|
||||
makerToken,
|
||||
IKyberHintHandler.TradeType.MaskIn,
|
||||
selectedReserves,
|
||||
new uint256[](0)
|
||||
emptySplits
|
||||
)
|
||||
);
|
||||
returns (bytes memory result)
|
||||
{
|
||||
return result;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
}
|
||||
}
|
||||
// If successful decode the hint
|
||||
if (didSucceed) {
|
||||
hint = abi.decode(resultData, (bytes));
|
||||
}
|
||||
return hint;
|
||||
}
|
||||
|
||||
function _sampleSellForApproximateBuyFromKyber(
|
||||
@@ -164,25 +178,22 @@ contract KyberSampler is
|
||||
)
|
||||
private
|
||||
view
|
||||
returns (uint256 buyAmount)
|
||||
returns (uint256)
|
||||
{
|
||||
(address makerToken, bytes memory hint) =
|
||||
abi.decode(makerTokenData, (address, bytes));
|
||||
(address takerToken, ) =
|
||||
abi.decode(takerTokenData, (address, bytes));
|
||||
(bool success, bytes memory resultData) =
|
||||
address(this).staticcall(abi.encodeWithSelector(
|
||||
this.sampleSellFromKyberNetwork.selector,
|
||||
hint,
|
||||
takerToken,
|
||||
makerToken,
|
||||
sellAmount
|
||||
));
|
||||
if (!success) {
|
||||
try
|
||||
this.sampleSellFromKyberNetwork
|
||||
(hint, takerToken, makerToken, sellAmount)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
return amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
// solhint-disable-next-line indent
|
||||
return abi.decode(resultData, (uint256));
|
||||
}
|
||||
|
||||
function sampleSellFromKyberNetwork(
|
||||
@@ -200,31 +211,30 @@ contract KyberSampler is
|
||||
return 0;
|
||||
}
|
||||
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getKyberNetworkProxyAddress().staticcall.gas(KYBER_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IKyberNetworkProxy(0).getExpectedRateAfterFee.selector,
|
||||
try
|
||||
IKyberNetworkProxy(_getKyberNetworkProxyAddress()).getExpectedRateAfterFee
|
||||
{gas: KYBER_CALL_GAS}
|
||||
(
|
||||
takerToken == _getWethAddress() ? KYBER_ETH_ADDRESS : takerToken,
|
||||
makerToken == _getWethAddress() ? KYBER_ETH_ADDRESS : makerToken,
|
||||
takerTokenAmount,
|
||||
0, // fee
|
||||
hint
|
||||
));
|
||||
uint256 rate = 0;
|
||||
if (didSucceed) {
|
||||
(rate) = abi.decode(resultData, (uint256));
|
||||
} else {
|
||||
)
|
||||
returns (uint256 rate)
|
||||
{
|
||||
uint256 makerTokenDecimals = _getTokenDecimals(makerToken);
|
||||
uint256 takerTokenDecimals = _getTokenDecimals(takerToken);
|
||||
makerTokenAmount =
|
||||
rate *
|
||||
takerTokenAmount *
|
||||
10 ** makerTokenDecimals /
|
||||
10 ** takerTokenDecimals /
|
||||
10 ** 18;
|
||||
return makerTokenAmount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 makerTokenDecimals = _getTokenDecimals(makerToken);
|
||||
uint256 takerTokenDecimals = _getTokenDecimals(takerToken);
|
||||
makerTokenAmount =
|
||||
rate *
|
||||
takerTokenAmount *
|
||||
10 ** makerTokenDecimals /
|
||||
10 ** takerTokenDecimals /
|
||||
10 ** 18;
|
||||
return makerTokenAmount;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
import "./interfaces/ILiquidityProvider.sol";
|
||||
import "./interfaces/ILiquidityProviderRegistry.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
@@ -66,23 +66,17 @@ contract LiquidityProviderSampler is
|
||||
}
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
providerAddress.staticcall.gas(DEFAULT_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
ILiquidityProvider(0).getSellQuote.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
takerTokenAmounts[i]
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
buyAmount = abi.decode(resultData, (uint256));
|
||||
}
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (buyAmount == 0) {
|
||||
try
|
||||
ILiquidityProvider(providerAddress).getSellQuote
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(takerToken, makerToken, takerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
{
|
||||
makerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,14 +130,15 @@ contract LiquidityProviderSampler is
|
||||
if (registryAddress == address(0)) {
|
||||
return address(0);
|
||||
}
|
||||
|
||||
bytes memory callData = abi.encodeWithSelector(
|
||||
ILiquidityProviderRegistry(0).getLiquidityProviderForMarket.selector,
|
||||
ILiquidityProviderRegistry.getLiquidityProviderForMarket.selector,
|
||||
takerToken,
|
||||
makerToken
|
||||
);
|
||||
(bool didSucceed, bytes memory returnData) = registryAddress.staticcall(callData);
|
||||
if (didSucceed && returnData.length == 32) {
|
||||
return LibBytes.readAddress(returnData, 12);
|
||||
return LibBytesV06.readAddress(returnData, 12);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,19 +155,16 @@ contract LiquidityProviderSampler is
|
||||
abi.decode(takerTokenData, (address, address));
|
||||
(address makerToken) =
|
||||
abi.decode(makerTokenData, (address));
|
||||
(bool success, bytes memory resultData) =
|
||||
address(this).staticcall(abi.encodeWithSelector(
|
||||
this.sampleSellsFromLiquidityProviderRegistry.selector,
|
||||
plpRegistryAddress,
|
||||
takerToken,
|
||||
makerToken,
|
||||
_toSingleValueArray(sellAmount)
|
||||
));
|
||||
if (!success) {
|
||||
try
|
||||
this.sampleSellsFromLiquidityProviderRegistry
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(plpRegistryAddress, takerToken, makerToken, _toSingleValueArray(sellAmount))
|
||||
returns (uint256[] memory amounts, address)
|
||||
{
|
||||
return amounts[0];
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
// solhint-disable-next-line indent
|
||||
(uint256[] memory amounts, ) = abi.decode(resultData, (uint256[], address));
|
||||
return amounts[0];
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IMStable.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
@@ -54,23 +53,17 @@ contract MStableSampler is
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
address(_getMUsdAddress()).staticcall.gas(DEFAULT_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IMStable(0).getSwapOutput.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
takerTokenAmounts[i]
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
(, , buyAmount) = abi.decode(resultData, (bool, string, uint256));
|
||||
}
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (buyAmount == 0) {
|
||||
try
|
||||
IMStable(_getMUsdAddress()).getSwapOutput
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(takerToken, makerToken, takerTokenAmounts[i])
|
||||
returns (bool, string memory, uint256 amount)
|
||||
{
|
||||
makerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,17 +105,15 @@ contract MStableSampler is
|
||||
abi.decode(takerTokenData, (address));
|
||||
(address makerToken) =
|
||||
abi.decode(makerTokenData, (address));
|
||||
(bool success, bytes memory resultData) =
|
||||
address(this).staticcall(abi.encodeWithSelector(
|
||||
this.sampleSellsFromMStable.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
_toSingleValueArray(sellAmount)
|
||||
));
|
||||
if (!success) {
|
||||
try
|
||||
this.sampleSellsFromMStable
|
||||
(takerToken, makerToken, _toSingleValueArray(sellAmount))
|
||||
returns (uint256[] memory amounts)
|
||||
{
|
||||
return amounts[0];
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
// solhint-disable-next-line indent
|
||||
return abi.decode(resultData, (uint256[]))[0];
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "./IMooniswap.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IMooniswap.sol";
|
||||
import "./ApproximateBuys.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
|
||||
@@ -37,6 +37,7 @@ contract MooniswapSampler is
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return pool The contract address for the pool
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromMooniswap(
|
||||
@@ -80,7 +81,7 @@ contract MooniswapSampler is
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256 makerTokenAmount)
|
||||
returns (uint256)
|
||||
{
|
||||
// Find the pool for the pair.
|
||||
IMooniswap pool = IMooniswap(
|
||||
@@ -88,26 +89,26 @@ contract MooniswapSampler is
|
||||
);
|
||||
// If there is no pool then return early
|
||||
if (address(pool) == address(0)) {
|
||||
return makerTokenAmount;
|
||||
return 0;
|
||||
}
|
||||
uint256 poolBalance = mooniswapTakerToken == address(0)
|
||||
? address(pool).balance
|
||||
: IERC20Token(mooniswapTakerToken).balanceOf(address(pool));
|
||||
: IERC20TokenV06(mooniswapTakerToken).balanceOf(address(pool));
|
||||
// If the pool balance is smaller than the sell amount
|
||||
// don't sample to avoid multiplication overflow in buys
|
||||
if (poolBalance < takerTokenAmount) {
|
||||
return makerTokenAmount;
|
||||
return 0;
|
||||
}
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
address(pool).staticcall.gas(MOONISWAP_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
pool.getReturn.selector,
|
||||
mooniswapTakerToken,
|
||||
mooniswapMakerToken,
|
||||
takerTokenAmount
|
||||
));
|
||||
if (didSucceed) {
|
||||
makerTokenAmount = abi.decode(resultData, (uint256));
|
||||
try
|
||||
pool.getReturn
|
||||
{gas: MOONISWAP_CALL_GAS}
|
||||
(mooniswapTakerToken, mooniswapMakerToken, takerTokenAmount)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
return amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +116,7 @@ contract MooniswapSampler is
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token sell amount for each sample.
|
||||
/// @return pool The contract address for the pool
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function sampleBuysFromMooniswap(
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./interfaces/IMultiBridge.sol";
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,21 +16,107 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
|
||||
|
||||
interface IExchange {
|
||||
|
||||
/// @dev V3 Order structure.
|
||||
struct Order {
|
||||
// Address that created the order.
|
||||
address makerAddress;
|
||||
// Address that is allowed to fill the order.
|
||||
// If set to 0, any address is allowed to fill the order.
|
||||
address takerAddress;
|
||||
// Address that will recieve fees when order is filled.
|
||||
address feeRecipientAddress;
|
||||
// Address that is allowed to call Exchange contract methods that affect this order.
|
||||
// If set to 0, any address is allowed to call these methods.
|
||||
address senderAddress;
|
||||
// Amount of makerAsset being offered by maker. Must be greater than 0.
|
||||
uint256 makerAssetAmount;
|
||||
// Amount of takerAsset being bid on by maker. Must be greater than 0.
|
||||
uint256 takerAssetAmount;
|
||||
// Fee paid to feeRecipient by maker when order is filled.
|
||||
uint256 makerFee;
|
||||
// Fee paid to feeRecipient by taker when order is filled.
|
||||
uint256 takerFee;
|
||||
// Timestamp in seconds at which order expires.
|
||||
uint256 expirationTimeSeconds;
|
||||
// Arbitrary number to facilitate uniqueness of the order's hash.
|
||||
uint256 salt;
|
||||
// Encoded data that can be decoded by a specified proxy contract when transferring makerAsset.
|
||||
// The leading bytes4 references the id of the asset proxy.
|
||||
bytes makerAssetData;
|
||||
// Encoded data that can be decoded by a specified proxy contract when transferring takerAsset.
|
||||
// The leading bytes4 references the id of the asset proxy.
|
||||
bytes takerAssetData;
|
||||
// Encoded data that can be decoded by a specified proxy contract when transferring makerFeeAsset.
|
||||
// The leading bytes4 references the id of the asset proxy.
|
||||
bytes makerFeeAssetData;
|
||||
// Encoded data that can be decoded by a specified proxy contract when transferring takerFeeAsset.
|
||||
// The leading bytes4 references the id of the asset proxy.
|
||||
bytes takerFeeAssetData;
|
||||
}
|
||||
|
||||
// A valid order remains fillable until it is expired, fully filled, or cancelled.
|
||||
// An order's status is unaffected by external factors, like account balances.
|
||||
enum OrderStatus {
|
||||
INVALID, // Default value
|
||||
INVALID_MAKER_ASSET_AMOUNT, // Order does not have a valid maker asset amount
|
||||
INVALID_TAKER_ASSET_AMOUNT, // Order does not have a valid taker asset amount
|
||||
FILLABLE, // Order is fillable
|
||||
EXPIRED, // Order has already expired
|
||||
FULLY_FILLED, // Order is fully filled
|
||||
CANCELLED // Order has been cancelled
|
||||
}
|
||||
|
||||
/// @dev Order information returned by `getOrderInfo()`.
|
||||
struct OrderInfo {
|
||||
OrderStatus orderStatus; // Status that describes order's validity and fillability.
|
||||
bytes32 orderHash; // EIP712 typed data hash of the order (see LibOrder.getTypedDataHash).
|
||||
uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.
|
||||
}
|
||||
|
||||
/// @dev Gets information about an order: status, hash, and amount filled.
|
||||
/// @param order Order to gather information on.
|
||||
/// @return orderInfo Information about the order and its state.
|
||||
function getOrderInfo(IExchange.Order calldata order)
|
||||
external
|
||||
view
|
||||
returns (IExchange.OrderInfo memory orderInfo);
|
||||
|
||||
/// @dev Verifies that a hash has been signed by the given signer.
|
||||
/// @param hash Any 32-byte hash.
|
||||
/// @param signature Proof that the hash has been signed by signer.
|
||||
/// @return isValid `true` if the signature is valid for the given hash and signer.
|
||||
function isValidHashSignature(
|
||||
bytes32 hash,
|
||||
address signerAddress,
|
||||
bytes calldata signature
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (bool isValid);
|
||||
|
||||
/// @dev Gets an asset proxy.
|
||||
/// @param assetProxyId Id of the asset proxy.
|
||||
/// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.
|
||||
function getAssetProxy(bytes4 assetProxyId)
|
||||
external
|
||||
view
|
||||
returns (address);
|
||||
}
|
||||
|
||||
contract NativeOrderSampler {
|
||||
using LibSafeMath for uint256;
|
||||
using LibBytes for bytes;
|
||||
using LibSafeMathV06 for uint256;
|
||||
using LibBytesV06 for bytes;
|
||||
|
||||
/// @dev The Exchange ERC20Proxy ID.
|
||||
bytes4 private constant ERC20_ASSET_PROXY_ID = 0xf47261b0;
|
||||
@@ -45,8 +131,8 @@ contract NativeOrderSampler {
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
uint256 fromTokenDecimals = LibERC20Token.decimals(makerTokenAddress);
|
||||
uint256 toTokenDecimals = LibERC20Token.decimals(takerTokenAddress);
|
||||
uint256 fromTokenDecimals = LibERC20TokenV06.compatDecimals(IERC20TokenV06(makerTokenAddress));
|
||||
uint256 toTokenDecimals = LibERC20TokenV06.compatDecimals(IERC20TokenV06(takerTokenAddress));
|
||||
return (fromTokenDecimals, toTokenDecimals);
|
||||
}
|
||||
|
||||
@@ -59,7 +145,7 @@ contract NativeOrderSampler {
|
||||
/// @return orderFillableTakerAssetAmounts How much taker asset can be filled
|
||||
/// by each order in `orders`.
|
||||
function getOrderFillableTakerAssetAmounts(
|
||||
LibOrder.Order[] memory orders,
|
||||
IExchange.Order[] memory orders,
|
||||
bytes[] memory orderSignatures,
|
||||
IExchange exchange
|
||||
)
|
||||
@@ -69,21 +155,21 @@ contract NativeOrderSampler {
|
||||
{
|
||||
orderFillableTakerAssetAmounts = new uint256[](orders.length);
|
||||
for (uint256 i = 0; i != orders.length; i++) {
|
||||
// solhint-disable indent
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
address(this)
|
||||
.staticcall
|
||||
.gas(DEFAULT_CALL_GAS)
|
||||
(abi.encodeWithSelector(
|
||||
this.getOrderFillableTakerAmount.selector,
|
||||
try
|
||||
this.getOrderFillableTakerAmount
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(
|
||||
orders[i],
|
||||
orderSignatures[i],
|
||||
exchange
|
||||
));
|
||||
// solhint-enable indent
|
||||
orderFillableTakerAssetAmounts[i] = didSucceed
|
||||
? abi.decode(resultData, (uint256))
|
||||
: 0;
|
||||
)
|
||||
returns (uint256 amount)
|
||||
{
|
||||
orderFillableTakerAssetAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
orderFillableTakerAssetAmounts[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +181,7 @@ contract NativeOrderSampler {
|
||||
/// @return orderFillableMakerAssetAmounts How much maker asset can be filled
|
||||
/// by each order in `orders`.
|
||||
function getOrderFillableMakerAssetAmounts(
|
||||
LibOrder.Order[] memory orders,
|
||||
IExchange.Order[] memory orders,
|
||||
bytes[] memory orderSignatures,
|
||||
IExchange exchange
|
||||
)
|
||||
@@ -112,7 +198,7 @@ contract NativeOrderSampler {
|
||||
// convert them to maker asset amounts.
|
||||
for (uint256 i = 0; i < orders.length; ++i) {
|
||||
if (orderFillableMakerAssetAmounts[i] != 0) {
|
||||
orderFillableMakerAssetAmounts[i] = LibMath.getPartialAmountCeil(
|
||||
orderFillableMakerAssetAmounts[i] = LibMathV06.getPartialAmountCeil(
|
||||
orderFillableMakerAssetAmounts[i],
|
||||
orders[i].takerAssetAmount,
|
||||
orders[i].makerAssetAmount
|
||||
@@ -124,10 +210,11 @@ contract NativeOrderSampler {
|
||||
/// @dev Get the fillable taker amount of an order, taking into account
|
||||
/// order state, maker fees, and maker balances.
|
||||
function getOrderFillableTakerAmount(
|
||||
LibOrder.Order memory order,
|
||||
IExchange.Order memory order,
|
||||
bytes memory signature,
|
||||
IExchange exchange
|
||||
)
|
||||
virtual
|
||||
public
|
||||
view
|
||||
returns (uint256 fillableTakerAmount)
|
||||
@@ -139,27 +226,27 @@ contract NativeOrderSampler {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LibOrder.OrderInfo memory orderInfo = exchange.getOrderInfo(order);
|
||||
if (orderInfo.orderStatus != LibOrder.OrderStatus.FILLABLE) {
|
||||
IExchange.OrderInfo memory orderInfo = exchange.getOrderInfo(order);
|
||||
if (orderInfo.orderStatus != IExchange.OrderStatus.FILLABLE) {
|
||||
return 0;
|
||||
}
|
||||
if (!exchange.isValidHashSignature(orderInfo.orderHash, order.makerAddress, signature)) {
|
||||
return 0;
|
||||
}
|
||||
address spender = exchange.getAssetProxy(ERC20_ASSET_PROXY_ID);
|
||||
IERC20Token makerToken = _getTokenFromERC20AssetData(order.makerAssetData);
|
||||
if (makerToken == IERC20Token(0)) {
|
||||
IERC20TokenV06 makerToken = _getTokenFromERC20AssetData(order.makerAssetData);
|
||||
if (makerToken == IERC20TokenV06(0)) {
|
||||
return 0;
|
||||
}
|
||||
IERC20Token makerFeeToken = order.makerFee > 0
|
||||
IERC20TokenV06 makerFeeToken = order.makerFee > 0
|
||||
? _getTokenFromERC20AssetData(order.makerFeeAssetData)
|
||||
: IERC20Token(0);
|
||||
: IERC20TokenV06(0);
|
||||
uint256 remainingTakerAmount = order.takerAssetAmount
|
||||
.safeSub(orderInfo.orderTakerAssetFilledAmount);
|
||||
fillableTakerAmount = remainingTakerAmount;
|
||||
// The total fillable maker amount is the remaining fillable maker amount
|
||||
// PLUS maker fees, if maker fees are denominated in the maker token.
|
||||
uint256 totalFillableMakerAmount = LibMath.safeGetPartialAmountFloor(
|
||||
uint256 totalFillableMakerAmount = LibMathV06.safeGetPartialAmountFloor(
|
||||
remainingTakerAmount,
|
||||
order.takerAssetAmount,
|
||||
makerFeeToken == makerToken
|
||||
@@ -168,14 +255,14 @@ contract NativeOrderSampler {
|
||||
);
|
||||
// The spendable amount of maker tokens (by the maker) is the lesser of
|
||||
// the maker's balance and the allowance they've granted to the ERC20Proxy.
|
||||
uint256 spendableMakerAmount = LibSafeMath.min256(
|
||||
uint256 spendableMakerAmount = LibSafeMathV06.min256(
|
||||
makerToken.balanceOf(order.makerAddress),
|
||||
makerToken.allowance(order.makerAddress, spender)
|
||||
);
|
||||
// Scale the fillable taker amount by the ratio of the maker's
|
||||
// spendable maker amount over the total fillable maker amount.
|
||||
if (spendableMakerAmount < totalFillableMakerAmount) {
|
||||
fillableTakerAmount = LibMath.getPartialAmountCeil(
|
||||
fillableTakerAmount = LibMathV06.getPartialAmountCeil(
|
||||
spendableMakerAmount,
|
||||
totalFillableMakerAmount,
|
||||
remainingTakerAmount
|
||||
@@ -183,15 +270,15 @@ contract NativeOrderSampler {
|
||||
}
|
||||
// If the maker fee is denominated in another token, constrain
|
||||
// the fillable taker amount by how much the maker can pay of that token.
|
||||
if (makerFeeToken != makerToken && makerFeeToken != IERC20Token(0)) {
|
||||
uint256 spendableExtraMakerFeeAmount = LibSafeMath.min256(
|
||||
if (makerFeeToken != makerToken && makerFeeToken != IERC20TokenV06(0)) {
|
||||
uint256 spendableExtraMakerFeeAmount = LibSafeMathV06.min256(
|
||||
makerFeeToken.balanceOf(order.makerAddress),
|
||||
makerFeeToken.allowance(order.makerAddress, spender)
|
||||
);
|
||||
if (spendableExtraMakerFeeAmount < order.makerFee) {
|
||||
fillableTakerAmount = LibSafeMath.min256(
|
||||
fillableTakerAmount = LibSafeMathV06.min256(
|
||||
fillableTakerAmount,
|
||||
LibMath.getPartialAmountCeil(
|
||||
LibMathV06.getPartialAmountCeil(
|
||||
spendableExtraMakerFeeAmount,
|
||||
order.makerFee,
|
||||
remainingTakerAmount
|
||||
@@ -204,16 +291,16 @@ contract NativeOrderSampler {
|
||||
function _getTokenFromERC20AssetData(bytes memory assetData)
|
||||
private
|
||||
pure
|
||||
returns (IERC20Token token)
|
||||
returns (IERC20TokenV06 token)
|
||||
{
|
||||
if (assetData.length == 0) {
|
||||
return IERC20Token(address(0));
|
||||
return IERC20TokenV06(address(0));
|
||||
}
|
||||
if (assetData.length != 36 ||
|
||||
assetData.readBytes4(0) != ERC20_ASSET_PROXY_ID)
|
||||
{
|
||||
return IERC20Token(address(0));
|
||||
return IERC20TokenV06(address(0));
|
||||
}
|
||||
return IERC20Token(assetData.readAddress(16));
|
||||
return IERC20TokenV06(assetData.readAddress(16));
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
|
||||
|
||||
contract SamplerUtils {
|
||||
@@ -28,11 +28,12 @@ contract SamplerUtils {
|
||||
/// @param tokenAddress Address of the token.
|
||||
/// @return decimals The decimal places for the token.
|
||||
function _getTokenDecimals(address tokenAddress)
|
||||
virtual
|
||||
internal
|
||||
view
|
||||
returns (uint8 decimals)
|
||||
{
|
||||
return LibERC20Token.decimals(tokenAddress);
|
||||
return LibERC20TokenV06.compatDecimals(IERC20TokenV06(tokenAddress));
|
||||
}
|
||||
|
||||
function _toSingleValueArray(uint256 v)
|
||||
|
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IShell.sol";
|
||||
|
||||
contract ShellSampler is
|
||||
@@ -48,23 +48,17 @@ contract ShellSampler is
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
address(_getShellAddress()).staticcall.gas(DEFAULT_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IShell(0).viewOriginSwap.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
takerTokenAmounts[i]
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
buyAmount = abi.decode(resultData, (uint256));
|
||||
}
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (buyAmount == 0) {
|
||||
try
|
||||
IShell(_getShellAddress()).viewOriginSwap
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(takerToken, makerToken, takerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
{
|
||||
makerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,23 +82,17 @@ contract ShellSampler is
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
address(_getShellAddress()).staticcall.gas(DEFAULT_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IShell(0).viewTargetSwap.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
makerTokenAmounts[i]
|
||||
));
|
||||
uint256 sellAmount = 0;
|
||||
if (didSucceed) {
|
||||
sellAmount = abi.decode(resultData, (uint256));
|
||||
}
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (sellAmount == 0) {
|
||||
try
|
||||
IShell(_getShellAddress()).viewTargetSwap
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(takerToken, makerToken, makerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
{
|
||||
takerTokenAmounts[i] = amount;
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
takerTokenAmounts[i] = sellAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IUniswapV2Router01.sol";
|
||||
|
||||
|
||||
@@ -47,21 +47,17 @@ contract SushiSwapSampler is
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
router.staticcall.gas(SUSHISWAP_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IUniswapV2Router01(0).getAmountsOut.selector,
|
||||
takerTokenAmounts[i],
|
||||
path
|
||||
));
|
||||
uint256 buyAmount = 0;
|
||||
if (didSucceed) {
|
||||
// solhint-disable-next-line indent
|
||||
buyAmount = abi.decode(resultData, (uint256[]))[path.length - 1];
|
||||
} else {
|
||||
try
|
||||
IUniswapV2Router01(router).getAmountsOut
|
||||
{gas: SUSHISWAP_CALL_GAS}
|
||||
(takerTokenAmounts[i], path)
|
||||
returns (uint256[] memory amounts)
|
||||
{
|
||||
makerTokenAmounts[i] = amounts[path.length - 1];
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
makerTokenAmounts[i] = buyAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,21 +79,17 @@ contract SushiSwapSampler is
|
||||
uint256 numSamples = makerTokenAmounts.length;
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
router.staticcall.gas(SUSHISWAP_CALL_GAS)(
|
||||
abi.encodeWithSelector(
|
||||
IUniswapV2Router01(0).getAmountsIn.selector,
|
||||
makerTokenAmounts[i],
|
||||
path
|
||||
));
|
||||
uint256 sellAmount = 0;
|
||||
if (didSucceed) {
|
||||
// solhint-disable-next-line indent
|
||||
sellAmount = abi.decode(resultData, (uint256[]))[0];
|
||||
} else {
|
||||
try
|
||||
IUniswapV2Router01(router).getAmountsIn
|
||||
{gas: SUSHISWAP_CALL_GAS}
|
||||
(makerTokenAmounts[i], path)
|
||||
returns (uint256[] memory amounts)
|
||||
{
|
||||
takerTokenAmounts[i] = amounts[0];
|
||||
} catch (bytes memory) {
|
||||
// Swallow failures, leaving all results as zero.
|
||||
break;
|
||||
}
|
||||
takerTokenAmounts[i] = sellAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
|
||||
|
||||
contract TwoHopSampler {
|
||||
using LibBytes for bytes;
|
||||
using LibBytesV06 for bytes;
|
||||
|
||||
struct HopInfo {
|
||||
uint256 sourceIndex;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
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.
|
||||
@@ -16,19 +16,25 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
import "./interfaces/IUniswapExchangeQuotes.sol";
|
||||
import "./SamplerUtils.sol";
|
||||
|
||||
|
||||
interface IUniswapExchangeFactory {
|
||||
|
||||
/// @dev Get the exchange for a token.
|
||||
/// @param tokenAddress The address of the token contract.
|
||||
function getExchange(address tokenAddress)
|
||||
external
|
||||
view
|
||||
returns (address);
|
||||
}
|
||||
|
||||
|
||||
contract UniswapSampler is
|
||||
DeploymentConstants,
|
||||
SamplerUtils
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user