chore: [asset swapper] sampler Solidity 0.6 + Bridge addresses in AS (#4)
* Refactor excess interfaces * Compiles on 0.6 * Refactored into try/catch * Rebase and Refactored to v06 * Handle invalid registry in LP * Update packages/asset-swapper/contracts/src/LiquidityProviderSampler.sol Co-authored-by: Lawrence Forman <lawrence@0xproject.com> * chore: [asset-swapper] Move Bridge Addresses and Gas schedule * curve->pool * lint * Refactor to fix module load order * Move FEE Schedule * rollup: Swerve/Sushi/SnowSwap/DODO (#7) * rollup: Swerve/Sushi * DODO Rollup + Snowswap Swerve * hardcode addresses temporarily * rebase * rename to SUSHISWAP_ROUTER * CHANGELOGs * CHANGELOGs Co-authored-by: Lawrence Forman <lawrence@0xproject.com>
This commit is contained in:
parent
8de0282d92
commit
99f5be8378
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "3.6.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add `SwerveBridge` and `SnowSwapBridge` (duplicate of `CurveBridge`)",
|
||||
"pr": 2707
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.5.0",
|
||||
"changes": [
|
||||
|
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;
|
||||
}
|
||||
}
|
@ -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": {
|
||||
|
@ -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 @@
|
||||
[
|
||||
{
|
||||
"version": "0.5.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add `Swerve`, `SnowSwap`, `DODO` and `SushiSwap` into FQT",
|
||||
"pr": 7
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.4.0",
|
||||
"changes": [
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
@ -65,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';
|
||||
@ -176,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,
|
||||
|
@ -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(
|
||||
|
@ -63,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';
|
||||
|
@ -87,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",
|
||||
|
@ -1,4 +1,17 @@
|
||||
[
|
||||
{
|
||||
"version": "4.8.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Moved Bridge addresses into Asset-swapper",
|
||||
"pr": 4
|
||||
},
|
||||
{
|
||||
"note": "Updated Sampler to Solidity 0.6",
|
||||
"pr": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1603487270,
|
||||
"version": "4.7.1",
|
||||
@ -172,8 +185,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
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
||||
|
||||
@ -45,21 +45,17 @@ contract UniswapV2Sampler is
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getUniswapV2Router01Address().staticcall.gas(UNISWAPV2_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(_getUniswapV2Router01Address()).getAmountsOut
|
||||
{gas: UNISWAPV2_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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,21 +75,17 @@ contract UniswapV2Sampler is
|
||||
uint256 numSamples = makerTokenAmounts.length;
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(bool didSucceed, bytes memory resultData) =
|
||||
_getUniswapV2Router01Address().staticcall.gas(UNISWAPV2_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(_getUniswapV2Router01Address()).getAmountsIn
|
||||
{gas: UNISWAPV2_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,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
|
||||
|
||||
interface IBalancer {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
// solhint-disable func-name-mixedcase
|
||||
|
@ -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;
|
||||
|
||||
|
||||
interface IEth2Dai {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
|
||||
// Keepin everything together
|
||||
interface IKyberNetwork {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
interface ILiquidityProvider {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
interface ILiquidityProviderRegistry {
|
||||
@ -25,7 +25,7 @@ interface ILiquidityProviderRegistry {
|
||||
/// (takerToken, makerToken), reverting if the pool does not exist.
|
||||
/// @param takerToken Taker asset managed by liquidity provider.
|
||||
/// @param makerToken Maker asset managed by liquidity provider.
|
||||
/// @return Address of the liquidity provider.
|
||||
/// @return providerAddress Address of the liquidity provider.
|
||||
function getLiquidityProviderForMarket(
|
||||
address takerToken,
|
||||
address makerToken
|
||||
|
@ -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;
|
||||
|
||||
|
||||
interface IMStable {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
|
||||
|
||||
interface IMooniswapRegistry {
|
@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
|
||||
|
||||
interface IMultiBridge {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
|
||||
|
||||
interface IShell {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
interface IUniswapExchangeQuotes {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
interface IUniswapV2Router01 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
@ -35,4 +35,4 @@ contract DummyLiquidityProvider
|
||||
{
|
||||
takerTokenAmount = buyAmount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ contract DummyLiquidityProviderRegistry
|
||||
/// @dev Returns the address of pool for a market given market (xAsset, yAsset), or reverts if pool does not exist.
|
||||
/// @param xToken First asset managed by pool.
|
||||
/// @param yToken Second asset managed by pool.
|
||||
/// @return Address of pool.
|
||||
/// @return poolAddress Address of pool.
|
||||
function getLiquidityProviderForMarket(
|
||||
address xToken,
|
||||
address yToken
|
||||
@ -41,4 +41,4 @@ contract DummyLiquidityProviderRegistry
|
||||
"Registry/MARKET_PAIR_NOT_SET"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
@ -15,12 +15,9 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
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-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "../src/ERC20BridgeSampler.sol";
|
||||
import "../src/interfaces/IEth2Dai.sol";
|
||||
import "../src/interfaces/IKyberNetwork.sol";
|
||||
@ -128,6 +125,7 @@ contract TestERC20BridgeSamplerUniswapExchange is
|
||||
function getEthToTokenInputPrice(
|
||||
uint256 ethSold
|
||||
)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256 tokensBought)
|
||||
@ -145,6 +143,7 @@ contract TestERC20BridgeSamplerUniswapExchange is
|
||||
function getEthToTokenOutputPrice(
|
||||
uint256 tokensBought
|
||||
)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256 ethSold)
|
||||
@ -162,6 +161,7 @@ contract TestERC20BridgeSamplerUniswapExchange is
|
||||
function getTokenToEthInputPrice(
|
||||
uint256 tokensSold
|
||||
)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256 ethBought)
|
||||
@ -179,6 +179,7 @@ contract TestERC20BridgeSamplerUniswapExchange is
|
||||
function getTokenToEthOutputPrice(
|
||||
uint256 ethBought
|
||||
)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256 tokensSold)
|
||||
@ -203,6 +204,7 @@ contract TestERC20BridgeSamplerUniswapV2Router01 is
|
||||
|
||||
// Deterministic `IUniswapV2Router01.getAmountsOut()`.
|
||||
function getAmountsOut(uint256 amountIn, address[] calldata path)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory amounts)
|
||||
@ -223,6 +225,7 @@ contract TestERC20BridgeSamplerUniswapV2Router01 is
|
||||
|
||||
// Deterministic `IUniswapV2Router01.getAmountsInt()`.
|
||||
function getAmountsIn(uint256 amountOut, address[] calldata path)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256[] memory amounts)
|
||||
@ -333,6 +336,7 @@ contract TestERC20BridgeSamplerKyberNetwork is
|
||||
}
|
||||
|
||||
function _getKyberNetworkProxyAddress()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address)
|
||||
@ -341,6 +345,7 @@ contract TestERC20BridgeSamplerKyberNetwork is
|
||||
}
|
||||
|
||||
function _getKyberHintHandlerAddress()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address)
|
||||
@ -362,6 +367,7 @@ contract TestERC20BridgeSamplerEth2Dai is
|
||||
address payToken,
|
||||
uint256 payAmount
|
||||
)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256 buyAmount)
|
||||
@ -381,6 +387,7 @@ contract TestERC20BridgeSamplerEth2Dai is
|
||||
address buyToken,
|
||||
uint256 buyAmount
|
||||
)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (uint256 payAmount)
|
||||
@ -414,6 +421,7 @@ contract TestERC20BridgeSamplerUniswapExchangeFactory is
|
||||
|
||||
// `IUniswapExchangeFactory.getExchange()`.
|
||||
function getExchange(address tokenAddress)
|
||||
override
|
||||
external
|
||||
view
|
||||
returns (address)
|
||||
@ -432,7 +440,7 @@ contract TestERC20BridgeSampler is
|
||||
TestERC20BridgeSamplerEth2Dai public eth2Dai;
|
||||
TestERC20BridgeSamplerKyberNetwork public kyber;
|
||||
|
||||
uint8 private constant MAX_ORDER_STATUS = uint8(LibOrder.OrderStatus.CANCELLED) + 1;
|
||||
uint8 private constant MAX_ORDER_STATUS = uint8(IExchange.OrderStatus.CANCELLED) + 1;
|
||||
|
||||
constructor() public ERC20BridgeSampler() {
|
||||
uniswap = new TestERC20BridgeSamplerUniswapExchangeFactory();
|
||||
@ -450,10 +458,11 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overridden to return deterministic states.
|
||||
function getOrderFillableTakerAmount(
|
||||
LibOrder.Order memory order,
|
||||
IExchange.Order memory order,
|
||||
bytes memory,
|
||||
IExchange
|
||||
)
|
||||
override
|
||||
public
|
||||
view
|
||||
returns (uint256 fillableTakerAmount)
|
||||
@ -463,6 +472,7 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overriden to return deterministic decimals.
|
||||
function _getTokenDecimals(address tokenAddress)
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (uint8 decimals)
|
||||
@ -472,6 +482,7 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overriden to point to a custom contract.
|
||||
function _getEth2DaiAddress()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address eth2daiAddress)
|
||||
@ -481,6 +492,7 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overriden to point to a custom contract.
|
||||
function _getUniswapExchangeFactoryAddress()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address uniswapAddress)
|
||||
@ -490,6 +502,7 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overriden to point to a custom contract.
|
||||
function _getUniswapV2Router01Address()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address uniswapV2RouterAddress)
|
||||
@ -499,6 +512,7 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overriden to point to a custom contract.
|
||||
function _getKyberNetworkProxyAddress()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address kyberAddress)
|
||||
@ -508,6 +522,7 @@ contract TestERC20BridgeSampler is
|
||||
|
||||
// Overriden to point to a custom contract.
|
||||
function _getKyberHintHandlerAddress()
|
||||
override
|
||||
internal
|
||||
view
|
||||
returns (address kyberAddress)
|
||||
|
@ -15,11 +15,9 @@
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
pragma solidity ^0.5.9;
|
||||
pragma solidity ^0.6;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "../src/NativeOrderSampler.sol";
|
||||
|
||||
|
||||
@ -43,7 +41,7 @@ contract TestNativeOrderSamplerToken {
|
||||
contract TestNativeOrderSampler is
|
||||
NativeOrderSampler
|
||||
{
|
||||
uint8 private constant MAX_ORDER_STATUS = uint8(LibOrder.OrderStatus.CANCELLED) + 1;
|
||||
uint8 private constant MAX_ORDER_STATUS = uint8(IExchange.OrderStatus.CANCELLED) + 1;
|
||||
bytes32 private constant VALID_SIGNATURE_HASH = keccak256(hex"01");
|
||||
|
||||
function createTokens(uint256 count)
|
||||
@ -78,17 +76,17 @@ contract TestNativeOrderSampler is
|
||||
}
|
||||
|
||||
// IExchange.getOrderInfo()
|
||||
function getOrderInfo(LibOrder.Order calldata order)
|
||||
function getOrderInfo(IExchange.Order calldata order)
|
||||
external
|
||||
pure
|
||||
returns (LibOrder.OrderInfo memory orderInfo)
|
||||
returns (IExchange.OrderInfo memory orderInfo)
|
||||
{
|
||||
// The order salt determines everything.
|
||||
orderInfo.orderHash = keccak256(abi.encode(order.salt));
|
||||
if (uint8(order.salt) == 0xFF) {
|
||||
orderInfo.orderStatus = LibOrder.OrderStatus.FULLY_FILLED;
|
||||
orderInfo.orderStatus = IExchange.OrderStatus.FULLY_FILLED;
|
||||
} else {
|
||||
orderInfo.orderStatus = LibOrder.OrderStatus.FILLABLE;
|
||||
orderInfo.orderStatus = IExchange.OrderStatus.FILLABLE;
|
||||
}
|
||||
// The expiration time is the filled taker asset amount.
|
||||
orderInfo.orderTakerAssetFilledAmount = order.expirationTimeSeconds;
|
||||
|
@ -38,7 +38,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "ERC20BridgeSampler,ILiquidityProvider,ILiquidityProviderRegistry,DummyLiquidityProviderRegistry,DummyLiquidityProvider",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalancerSampler|CurveSampler|DODOSampler|DummyLiquidityProvider|DummyLiquidityProviderRegistry|ERC20BridgeSampler|Eth2DaiSampler|IBalancer|ICurve|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SushiSwapSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler).json",
|
||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalancerSampler|CurveSampler|DODOSampler|DeploymentConstants|DummyLiquidityProvider|DummyLiquidityProviderRegistry|ERC20BridgeSampler|Eth2DaiSampler|IBalancer|ICurve|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SushiSwapSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler).json",
|
||||
"postpublish": {
|
||||
"assets": []
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { ChainId } from '@0x/contract-addresses';
|
||||
import { BigNumber, logUtils } from '@0x/utils';
|
||||
|
||||
import {
|
||||
@ -42,7 +43,7 @@ const PROTOCOL_FEE_MULTIPLIER = new BigNumber(70000);
|
||||
const MARKET_UTILS_AMOUNT_BUFFER_PERCENTAGE = 0.5;
|
||||
|
||||
const DEFAULT_SWAP_QUOTER_OPTS: SwapQuoterOpts = {
|
||||
chainId: MAINNET_CHAIN_ID,
|
||||
chainId: ChainId.Mainnet,
|
||||
orderRefreshIntervalMs: 10000, // 10 seconds
|
||||
...DEFAULT_ORDER_PRUNER_OPTS,
|
||||
samplerGasLimit: 250e6,
|
||||
@ -95,6 +96,21 @@ export const DEFAULT_INFO_LOGGER: LogFunction = (obj, msg) =>
|
||||
export const DEFAULT_WARNING_LOGGER: LogFunction = (obj, msg) =>
|
||||
logUtils.warn(`${msg ? `${msg}: ` : ''}${JSON.stringify(obj)}`);
|
||||
|
||||
// This feature flag allows us to merge the price-aware RFQ pricing
|
||||
// project while still controlling when to activate the feature. We plan to do some
|
||||
// data analysis work and address some of the issues with maker fillable amounts
|
||||
// in later milestones. Once the feature is fully rolled out and is providing value
|
||||
// and we have assessed that there is no user impact, we will proceed in cleaning up
|
||||
// the feature flag. When that time comes, follow this PR to "undo" the feature flag:
|
||||
// https://github.com/0xProject/0x-monorepo/pull/2735
|
||||
export const IS_PRICE_AWARE_RFQ_ENABLED: boolean = false;
|
||||
|
||||
export {
|
||||
BRIDGE_ADDRESSES_BY_CHAIN,
|
||||
DEFAULT_FEE_SCHEDULE,
|
||||
DEFAULT_GAS_SCHEDULE,
|
||||
} from './utils/market_operation_utils/constants';
|
||||
|
||||
export const constants = {
|
||||
ETH_GAS_STATION_API_URL,
|
||||
PROTOCOL_FEE_MULTIPLIER,
|
||||
@ -122,12 +138,3 @@ export const constants = {
|
||||
DEFAULT_INFO_LOGGER,
|
||||
DEFAULT_WARNING_LOGGER,
|
||||
};
|
||||
|
||||
// This feature flag allows us to merge the price-aware RFQ pricing
|
||||
// project while still controlling when to activate the feature. We plan to do some
|
||||
// data analysis work and address some of the issues with maker fillable amounts
|
||||
// in later milestones. Once the feature is fully rolled out and is providing value
|
||||
// and we have assessed that there is no user impact, we will proceed in cleaning up
|
||||
// the feature flag. When that time comes, follow this PR to "undo" the feature flag:
|
||||
// https://github.com/0xProject/0x-monorepo/pull/2735
|
||||
export const IS_PRICE_AWARE_RFQ_ENABLED: boolean = false;
|
||||
|
@ -88,6 +88,7 @@ export { getSwapMinBuyAmount } from './quote_consumers/utils';
|
||||
export { SwapQuoter } from './swap_quoter';
|
||||
export {
|
||||
AffiliateFee,
|
||||
AssetSwapperContractAddresses,
|
||||
CalldataInfo,
|
||||
ExchangeProxyContractOpts,
|
||||
ExchangeProxyRefundReceiver,
|
||||
@ -119,7 +120,11 @@ export {
|
||||
SwapQuoterRfqtOpts,
|
||||
} from './types';
|
||||
export { affiliateFeeUtils } from './utils/affiliate_fee_utils';
|
||||
export { SOURCE_FLAGS } from './utils/market_operation_utils/constants';
|
||||
export {
|
||||
BRIDGE_ADDRESSES_BY_CHAIN,
|
||||
DEFAULT_GAS_SCHEDULE,
|
||||
SOURCE_FLAGS,
|
||||
} from './utils/market_operation_utils/constants';
|
||||
export {
|
||||
Parameters,
|
||||
SamplerContractCall,
|
||||
@ -150,13 +155,13 @@ export {
|
||||
NativeCollapsedFill,
|
||||
NativeFillData,
|
||||
OptimizedMarketOrder,
|
||||
SnowSwapFillData,
|
||||
SnowSwapInfo,
|
||||
SourceInfo,
|
||||
SourceQuoteOperation,
|
||||
SushiSwapFillData,
|
||||
SwerveFillData,
|
||||
SwerveInfo,
|
||||
SnowSwapFillData,
|
||||
SnowSwapInfo,
|
||||
TokenAdjacencyGraph,
|
||||
UniswapV2FillData,
|
||||
} from './utils/market_operation_utils/types';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ContractAddresses, getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
|
||||
import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
|
||||
import { DevUtilsContract } from '@0x/contract-wrappers';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import { assetDataUtils, SignedOrder } from '@0x/order-utils';
|
||||
@ -8,8 +8,9 @@ import { BlockParamLiteral, SupportedProvider, ZeroExProvider } from 'ethereum-t
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { constants, IS_PRICE_AWARE_RFQ_ENABLED } from './constants';
|
||||
import { BRIDGE_ADDRESSES_BY_CHAIN, constants, IS_PRICE_AWARE_RFQ_ENABLED } from './constants';
|
||||
import {
|
||||
AssetSwapperContractAddresses,
|
||||
CalculateSwapQuoteOpts,
|
||||
LiquidityForTakerMakerAssetDataPair,
|
||||
MarketBuySwapQuote,
|
||||
@ -48,7 +49,7 @@ export class SwapQuoter {
|
||||
public readonly expiryBufferMs: number;
|
||||
public readonly chainId: number;
|
||||
public readonly permittedOrderFeeTypes: Set<OrderPrunerPermittedFeeTypes>;
|
||||
private readonly _contractAddresses: ContractAddresses;
|
||||
private readonly _contractAddresses: AssetSwapperContractAddresses;
|
||||
private readonly _protocolFeeUtils: ProtocolFeeUtils;
|
||||
private readonly _swapQuoteCalculator: SwapQuoteCalculator;
|
||||
private readonly _devUtilsContract: DevUtilsContract;
|
||||
@ -178,7 +179,10 @@ export class SwapQuoter {
|
||||
this.permittedOrderFeeTypes = permittedOrderFeeTypes;
|
||||
|
||||
this._rfqtOptions = rfqt;
|
||||
this._contractAddresses = options.contractAddresses || getContractAddressesForChainOrThrow(chainId);
|
||||
this._contractAddresses = options.contractAddresses || {
|
||||
...getContractAddressesForChainOrThrow(chainId),
|
||||
...BRIDGE_ADDRESSES_BY_CHAIN[chainId],
|
||||
};
|
||||
this._devUtilsContract = new DevUtilsContract(this._contractAddresses.devUtils, provider);
|
||||
this._protocolFeeUtils = ProtocolFeeUtils.getInstance(
|
||||
constants.PROTOCOL_FEE_UTILS_POLLING_INTERVAL_IN_MS,
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { ChainId } from '@0x/contract-addresses';
|
||||
import { BlockParam, ContractAddresses, GethCallOverrides } from '@0x/contract-wrappers';
|
||||
import { TakerRequestQueryParams } from '@0x/quote-server';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
@ -282,6 +283,8 @@ export interface SwapQuoterRfqtOpts {
|
||||
infoLogger?: LogFunction;
|
||||
}
|
||||
|
||||
export type AssetSwapperContractAddresses = ContractAddresses & BridgeContractAddresses;
|
||||
|
||||
/**
|
||||
* chainId: The ethereum chain id. Defaults to 1 (mainnet).
|
||||
* orderRefreshIntervalMs: The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s).
|
||||
@ -290,11 +293,11 @@ export interface SwapQuoterRfqtOpts {
|
||||
* samplerGasLimit: The gas limit used when querying the sampler contract. Defaults to 36e6
|
||||
*/
|
||||
export interface SwapQuoterOpts extends OrderPrunerOpts {
|
||||
chainId: number;
|
||||
chainId: ChainId;
|
||||
orderRefreshIntervalMs: number;
|
||||
expiryBufferMs: number;
|
||||
ethereumRpcUrl?: string;
|
||||
contractAddresses?: ContractAddresses;
|
||||
contractAddresses?: AssetSwapperContractAddresses;
|
||||
samplerGasLimit?: number;
|
||||
liquidityProviderRegistryAddress?: string;
|
||||
multiBridgeAddress?: string;
|
||||
@ -380,3 +383,24 @@ export interface SamplerOverrides {
|
||||
}
|
||||
|
||||
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
||||
/**
|
||||
* The Contract addresses of the deployed Bridges
|
||||
*/
|
||||
export interface BridgeContractAddresses {
|
||||
uniswapBridge: string;
|
||||
uniswapV2Bridge: string;
|
||||
eth2DaiBridge: string;
|
||||
kyberBridge: string;
|
||||
curveBridge: string;
|
||||
multiBridge: string;
|
||||
balancerBridge: string;
|
||||
bancorBridge: string;
|
||||
mStableBridge: string;
|
||||
mooniswapBridge: string;
|
||||
sushiswapBridge: string;
|
||||
shellBridge: string;
|
||||
dodoBridge: string;
|
||||
creamBridge: string;
|
||||
swerveBridge: string;
|
||||
snowswapBridge: string;
|
||||
}
|
||||
|
@ -1,33 +1,51 @@
|
||||
import { ChainId } from '@0x/contract-addresses';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { BridgeContractAddresses } from '../../types';
|
||||
|
||||
import { SourceFilters } from './source_filters';
|
||||
import { CurveFunctionSelectors, CurveInfo, ERC20BridgeSource, GetMarketOrdersOpts } from './types';
|
||||
import {
|
||||
CurveFillData,
|
||||
CurveFunctionSelectors,
|
||||
CurveInfo,
|
||||
DODOFillData,
|
||||
ERC20BridgeSource,
|
||||
FeeSchedule,
|
||||
FillData,
|
||||
GetMarketOrdersOpts,
|
||||
MultiHopFillData,
|
||||
SushiSwapFillData,
|
||||
UniswapV2FillData,
|
||||
} from './types';
|
||||
|
||||
// tslint:disable: custom-no-magic-numbers no-bitwise
|
||||
|
||||
/**
|
||||
* Valid sources for market sell.
|
||||
*/
|
||||
export const SELL_SOURCE_FILTER = new SourceFilters([
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
// Bancor is sampled off-chain, but this list should only include on-chain sources (used in ERC20BridgeSampler)
|
||||
// ERC20BridgeSource.Bancor,
|
||||
ERC20BridgeSource.MStable,
|
||||
ERC20BridgeSource.Mooniswap,
|
||||
ERC20BridgeSource.Swerve,
|
||||
ERC20BridgeSource.SnowSwap,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
]);
|
||||
export const SELL_SOURCE_FILTER = new SourceFilters(
|
||||
[
|
||||
ERC20BridgeSource.Native,
|
||||
ERC20BridgeSource.Uniswap,
|
||||
ERC20BridgeSource.UniswapV2,
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Curve,
|
||||
ERC20BridgeSource.Balancer,
|
||||
// Bancor is sampled off-chain, but this list should only include on-chain sources (used in ERC20BridgeSampler)
|
||||
// ERC20BridgeSource.Bancor,
|
||||
ERC20BridgeSource.MStable,
|
||||
ERC20BridgeSource.Mooniswap,
|
||||
ERC20BridgeSource.Swerve,
|
||||
ERC20BridgeSource.SnowSwap,
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
],
|
||||
[ERC20BridgeSource.MultiBridge],
|
||||
);
|
||||
|
||||
/**
|
||||
* Valid sources for market buy.
|
||||
@ -55,22 +73,10 @@ export const BUY_SOURCE_FILTER = new SourceFilters(
|
||||
[ERC20BridgeSource.MultiBridge],
|
||||
);
|
||||
|
||||
export const DEFAULT_GET_MARKET_ORDERS_OPTS: GetMarketOrdersOpts = {
|
||||
// tslint:disable-next-line: custom-no-magic-numbers
|
||||
runLimit: 2 ** 15,
|
||||
excludedSources: [],
|
||||
excludedFeeSources: [],
|
||||
includedSources: [],
|
||||
bridgeSlippage: 0.005,
|
||||
maxFallbackSlippage: 0.05,
|
||||
numSamples: 13,
|
||||
sampleDistributionBase: 1.05,
|
||||
feeSchedule: {},
|
||||
gasSchedule: {},
|
||||
exchangeProxyOverhead: () => ZERO_AMOUNT,
|
||||
allowFallback: true,
|
||||
shouldGenerateQuoteReport: false,
|
||||
};
|
||||
/**
|
||||
* 0x Protocol Fee Multiplier
|
||||
*/
|
||||
export const PROTOCOL_FEE_MULTIPLIER = new BigNumber(70000);
|
||||
|
||||
/**
|
||||
* Sources to poll for ETH fee price estimates.
|
||||
@ -283,3 +289,154 @@ export const ONE_SECOND_MS = 1000;
|
||||
export const NULL_BYTES = '0x';
|
||||
export const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
export const COMPARISON_PRICE_DECIMALS = 5;
|
||||
|
||||
const EMPTY_BRIDGE_ADDRESSES: BridgeContractAddresses = {
|
||||
uniswapBridge: NULL_ADDRESS,
|
||||
uniswapV2Bridge: NULL_ADDRESS,
|
||||
eth2DaiBridge: NULL_ADDRESS,
|
||||
kyberBridge: NULL_ADDRESS,
|
||||
curveBridge: NULL_ADDRESS,
|
||||
multiBridge: NULL_ADDRESS,
|
||||
balancerBridge: NULL_ADDRESS,
|
||||
bancorBridge: NULL_ADDRESS,
|
||||
mStableBridge: NULL_ADDRESS,
|
||||
mooniswapBridge: NULL_ADDRESS,
|
||||
sushiswapBridge: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
snowswapBridge: NULL_ADDRESS,
|
||||
swerveBridge: NULL_ADDRESS,
|
||||
};
|
||||
|
||||
export const BRIDGE_ADDRESSES_BY_CHAIN: { [chainId in ChainId]: BridgeContractAddresses } = {
|
||||
[ChainId.Mainnet]: {
|
||||
uniswapBridge: '0x36691c4f426eb8f42f150ebde43069a31cb080ad',
|
||||
uniswapV2Bridge: '0xdcd6011f4c6b80e470d9487f5871a0cba7c93f48',
|
||||
kyberBridge: '0xadd97271402590564ddd8ad23cb5317b1fb0fffb',
|
||||
eth2DaiBridge: '0x991c745401d5b5e469b8c3e2cb02c748f08754f1',
|
||||
curveBridge: '0x1796cd592d19e3bcd744fbb025bb61a6d8cb2c09',
|
||||
multiBridge: '0xc03117a8c9bde203f70aa911cb64a7a0df5ba1e1',
|
||||
balancerBridge: '0xfe01821ca163844203220cd08e4f2b2fb43ae4e4',
|
||||
bancorBridge: '0x259897d9699553edbdf8538599242354e957fb94',
|
||||
mStableBridge: '0x2bf04fcea05f0989a14d9afa37aa376baca6b2b3',
|
||||
mooniswapBridge: '0x02b7eca484ad960fca3f7709e0b2ac81eec3069c',
|
||||
sushiswapBridge: '0x47ed0262a0b688dcb836d254c6a2e96b6c48a9f5',
|
||||
shellBridge: '0x21fb3862eed7911e0f8219a077247b849846728d',
|
||||
dodoBridge: '0xe9da66965a9344aab2167e6813c03f043cc7a6ca',
|
||||
creamBridge: '0xb9d4bf2c8dab828f4ffb656acdb6c2b497d44f25',
|
||||
swerveBridge: '0xf9786d5eb1de47fa56a8f7bb387653c6d410bfee',
|
||||
snowswapBridge: '0xb1dbe83d15236ec10fdb214c6b89774b454754fd',
|
||||
},
|
||||
[ChainId.Kovan]: {
|
||||
...EMPTY_BRIDGE_ADDRESSES,
|
||||
uniswapBridge: '0x0e85f89f29998df65402391478e5924700c0079d',
|
||||
uniswapV2Bridge: '0x7b3530a635d099de0534dc27e46cd7c57578c3c8',
|
||||
eth2DaiBridge: '0x2d47147429b474d2e4f83e658015858a1312ed5b',
|
||||
kyberBridge: '0xaecfa25920f892b6eb496e1f6e84037f59da7f44',
|
||||
curveBridge: '0x81c0ab53a7352d2e97f682a37cba44e54647eefb',
|
||||
balancerBridge: '0x407b4128e9ecad8769b2332312a9f655cb9f5f3a',
|
||||
},
|
||||
[ChainId.Rinkeby]: EMPTY_BRIDGE_ADDRESSES,
|
||||
[ChainId.Ropsten]: EMPTY_BRIDGE_ADDRESSES,
|
||||
[ChainId.Ganache]: EMPTY_BRIDGE_ADDRESSES,
|
||||
};
|
||||
|
||||
// tslint:disable:custom-no-magic-numbers
|
||||
export const DEFAULT_GAS_SCHEDULE: FeeSchedule = {
|
||||
[ERC20BridgeSource.Native]: () => 150e3,
|
||||
[ERC20BridgeSource.Uniswap]: () => 90e3,
|
||||
[ERC20BridgeSource.LiquidityProvider]: () => 140e3,
|
||||
[ERC20BridgeSource.Eth2Dai]: () => 400e3,
|
||||
[ERC20BridgeSource.Kyber]: () => 500e3,
|
||||
[ERC20BridgeSource.Curve]: fillData => {
|
||||
const poolAddress = (fillData as CurveFillData).pool.poolAddress.toLowerCase();
|
||||
switch (poolAddress) {
|
||||
case '0xa5407eae9ba41422680e2e00537571bcc53efbfd':
|
||||
case '0x93054188d876f558f4a66b2ef1d97d16edf0895b':
|
||||
case '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714':
|
||||
case '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7':
|
||||
return 150e3;
|
||||
case '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56':
|
||||
return 750e3;
|
||||
case '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51':
|
||||
return 850e3;
|
||||
case '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27':
|
||||
return 1e6;
|
||||
case '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c':
|
||||
return 600e3;
|
||||
default:
|
||||
throw new Error(`Unrecognized Curve address: ${poolAddress}`);
|
||||
}
|
||||
},
|
||||
[ERC20BridgeSource.MultiBridge]: () => 350e3,
|
||||
[ERC20BridgeSource.UniswapV2]: (fillData?: FillData) => {
|
||||
// TODO: Different base cost if to/from ETH.
|
||||
let gas = 90e3;
|
||||
const path = (fillData as UniswapV2FillData).tokenAddressPath;
|
||||
if (path.length > 2) {
|
||||
gas += (path.length - 2) * 60e3; // +60k for each hop.
|
||||
}
|
||||
return gas;
|
||||
},
|
||||
[ERC20BridgeSource.SushiSwap]: (fillData?: FillData) => {
|
||||
// TODO: Different base cost if to/from ETH.
|
||||
let gas = 95e3;
|
||||
const path = (fillData as SushiSwapFillData).tokenAddressPath;
|
||||
if (path.length > 2) {
|
||||
gas += (path.length - 2) * 60e3; // +60k for each hop.
|
||||
}
|
||||
return gas;
|
||||
},
|
||||
[ERC20BridgeSource.Balancer]: () => 120e3,
|
||||
[ERC20BridgeSource.Cream]: () => 300e3,
|
||||
[ERC20BridgeSource.MStable]: () => 700e3,
|
||||
[ERC20BridgeSource.Mooniswap]: () => 220e3,
|
||||
[ERC20BridgeSource.Swerve]: () => 150e3,
|
||||
[ERC20BridgeSource.Shell]: () => 300e3,
|
||||
[ERC20BridgeSource.MultiHop]: (fillData?: FillData) => {
|
||||
const firstHop = (fillData as MultiHopFillData).firstHopSource;
|
||||
const secondHop = (fillData as MultiHopFillData).secondHopSource;
|
||||
const firstHopGas = DEFAULT_GAS_SCHEDULE[firstHop.source]!(firstHop.fillData);
|
||||
const secondHopGas = DEFAULT_GAS_SCHEDULE[secondHop.source]!(secondHop.fillData);
|
||||
return new BigNumber(firstHopGas)
|
||||
.plus(secondHopGas)
|
||||
.plus(30e3)
|
||||
.toNumber();
|
||||
},
|
||||
[ERC20BridgeSource.Dodo]: (fillData?: FillData) => {
|
||||
const isSellBase = (fillData as DODOFillData).isSellBase;
|
||||
// Sell base is cheaper as it is natively supported
|
||||
// sell quote requires additional calculation and overhead
|
||||
return isSellBase ? 440e3 : 540e3;
|
||||
},
|
||||
};
|
||||
|
||||
export const DEFAULT_FEE_SCHEDULE: FeeSchedule = Object.assign(
|
||||
{},
|
||||
...(Object.keys(DEFAULT_GAS_SCHEDULE) as ERC20BridgeSource[]).map(k => ({
|
||||
[k]:
|
||||
k === ERC20BridgeSource.Native
|
||||
? (fillData: FillData) => PROTOCOL_FEE_MULTIPLIER.plus(DEFAULT_GAS_SCHEDULE[k]!(fillData))
|
||||
: (fillData: FillData) => DEFAULT_GAS_SCHEDULE[k]!(fillData),
|
||||
})),
|
||||
);
|
||||
|
||||
// tslint:enable:custom-no-magic-numbers
|
||||
|
||||
export const DEFAULT_GET_MARKET_ORDERS_OPTS: GetMarketOrdersOpts = {
|
||||
// tslint:disable-next-line: custom-no-magic-numbers
|
||||
runLimit: 2 ** 15,
|
||||
excludedSources: [],
|
||||
excludedFeeSources: [],
|
||||
includedSources: [],
|
||||
bridgeSlippage: 0.005,
|
||||
maxFallbackSlippage: 0.05,
|
||||
numSamples: 13,
|
||||
sampleDistributionBase: 1.05,
|
||||
feeSchedule: DEFAULT_FEE_SCHEDULE,
|
||||
gasSchedule: DEFAULT_GAS_SCHEDULE,
|
||||
exchangeProxyOverhead: () => ZERO_AMOUNT,
|
||||
allowFallback: true,
|
||||
shouldGenerateQuoteReport: false,
|
||||
};
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { ContractAddresses } from '@0x/contract-addresses';
|
||||
import { Web3Wrapper } from '@0x/dev-utils';
|
||||
import { RFQTIndicativeQuote } from '@0x/quote-server';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber, NULL_ADDRESS } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { IS_PRICE_AWARE_RFQ_ENABLED } from '../../constants';
|
||||
import { MarketOperation, Omit } from '../../types';
|
||||
import { AssetSwapperContractAddresses, MarketOperation, Omit } from '../../types';
|
||||
import { QuoteRequestor } from '../quote_requestor';
|
||||
|
||||
import { generateQuoteReport, QuoteReport } from './../quote_report_generator';
|
||||
@ -106,7 +105,7 @@ export class MarketOperationUtils {
|
||||
|
||||
constructor(
|
||||
private readonly _sampler: DexOrderSampler,
|
||||
private readonly contractAddresses: ContractAddresses,
|
||||
private readonly contractAddresses: AssetSwapperContractAddresses,
|
||||
private readonly _orderDomain: OrderDomain,
|
||||
private readonly _liquidityProviderRegistry: string = NULL_ADDRESS,
|
||||
private readonly _tokenAdjacencyGraph: TokenAdjacencyGraph = {},
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { ContractAddresses } from '@0x/contract-addresses';
|
||||
import { assetDataUtils, ERC20AssetData, generatePseudoRandomSalt, orderCalculationUtils } from '@0x/order-utils';
|
||||
import { RFQTIndicativeQuote } from '@0x/quote-server';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { AbiEncoder, BigNumber } from '@0x/utils';
|
||||
|
||||
import { MarketOperation, SignedOrderWithFillableAmounts } from '../../types';
|
||||
import { AssetSwapperContractAddresses, MarketOperation, SignedOrderWithFillableAmounts } from '../../types';
|
||||
|
||||
import {
|
||||
ERC20_PROXY_ID,
|
||||
@ -135,7 +134,7 @@ export interface CreateOrderFromPathOpts {
|
||||
inputToken: string;
|
||||
outputToken: string;
|
||||
orderDomain: OrderDomain;
|
||||
contractAddresses: ContractAddresses;
|
||||
contractAddresses: AssetSwapperContractAddresses;
|
||||
bridgeSlippage: number;
|
||||
}
|
||||
|
||||
@ -182,9 +181,9 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath
|
||||
case ERC20BridgeSource.Curve:
|
||||
return opts.contractAddresses.curveBridge;
|
||||
case ERC20BridgeSource.Swerve:
|
||||
return opts.contractAddresses.curveBridge;
|
||||
return opts.contractAddresses.swerveBridge;
|
||||
case ERC20BridgeSource.SnowSwap:
|
||||
return opts.contractAddresses.curveBridge;
|
||||
return opts.contractAddresses.snowswapBridge;
|
||||
case ERC20BridgeSource.Bancor:
|
||||
return opts.contractAddresses.bancorBridge;
|
||||
case ERC20BridgeSource.Balancer:
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { SupportedProvider } from '@0x/dev-utils';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { BigNumber, NULL_ADDRESS } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { ERC20BridgeSamplerContract } from '../../wrappers';
|
||||
@ -1054,7 +1054,7 @@ export class SamplerOperations {
|
||||
const _sources = BATCH_SOURCE_FILTERS.exclude(
|
||||
liquidityProviderRegistryAddress ? [] : [ERC20BridgeSource.LiquidityProvider],
|
||||
)
|
||||
.exclude(multiBridgeAddress ? [] : [ERC20BridgeSource.MultiBridge])
|
||||
.exclude(multiBridgeAddress || multiBridgeAddress === NULL_ADDRESS ? [] : [ERC20BridgeSource.MultiBridge])
|
||||
.getAllowed(sources);
|
||||
return _.flatten(
|
||||
_sources.map(
|
||||
|
@ -8,6 +8,7 @@ import { ContractArtifact } from 'ethereum-types';
|
||||
import * as ApproximateBuys from '../test/generated-artifacts/ApproximateBuys.json';
|
||||
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.json';
|
||||
import * as CurveSampler from '../test/generated-artifacts/CurveSampler.json';
|
||||
import * as DeploymentConstants from '../test/generated-artifacts/DeploymentConstants.json';
|
||||
import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
|
||||
import * as DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json';
|
||||
import * as DummyLiquidityProviderRegistry from '../test/generated-artifacts/DummyLiquidityProviderRegistry.json';
|
||||
@ -44,9 +45,9 @@ export const artifacts = {
|
||||
BalancerSampler: BalancerSampler as ContractArtifact,
|
||||
CurveSampler: CurveSampler as ContractArtifact,
|
||||
DODOSampler: DODOSampler as ContractArtifact,
|
||||
DeploymentConstants: DeploymentConstants as ContractArtifact,
|
||||
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
|
||||
Eth2DaiSampler: Eth2DaiSampler as ContractArtifact,
|
||||
IMooniswap: IMooniswap as ContractArtifact,
|
||||
KyberSampler: KyberSampler as ContractArtifact,
|
||||
LiquidityProviderSampler: LiquidityProviderSampler as ContractArtifact,
|
||||
MStableSampler: MStableSampler as ContractArtifact,
|
||||
@ -66,6 +67,7 @@ export const artifacts = {
|
||||
ILiquidityProvider: ILiquidityProvider as ContractArtifact,
|
||||
ILiquidityProviderRegistry: ILiquidityProviderRegistry as ContractArtifact,
|
||||
IMStable: IMStable as ContractArtifact,
|
||||
IMooniswap: IMooniswap as ContractArtifact,
|
||||
IMultiBridge: IMultiBridge as ContractArtifact,
|
||||
IShell: IShell as ContractArtifact,
|
||||
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
|
||||
|
@ -1,5 +1,5 @@
|
||||
// tslint:disable: no-unbound-method
|
||||
import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
|
||||
import { ChainId, getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
|
||||
import {
|
||||
assertRoughlyEquals,
|
||||
constants,
|
||||
@ -9,10 +9,10 @@ import {
|
||||
Numberish,
|
||||
randomAddress,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { Web3Wrapper } from '@0x/dev-utils';
|
||||
import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils';
|
||||
import { AssetProxyId, ERC20BridgeAssetData, SignedOrder } from '@0x/types';
|
||||
import { BigNumber, fromTokenUnitAmount, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as _ from 'lodash';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
@ -21,6 +21,7 @@ import { IS_PRICE_AWARE_RFQ_ENABLED } from '../src/constants';
|
||||
import { getRfqtIndicativeQuotesAsync, MarketOperationUtils } from '../src/utils/market_operation_utils/';
|
||||
import { BalancerPoolsCache } from '../src/utils/market_operation_utils/balancer_utils';
|
||||
import {
|
||||
BRIDGE_ADDRESSES_BY_CHAIN,
|
||||
BUY_SOURCE_FILTER,
|
||||
POSITIVE_INF,
|
||||
SELL_SOURCE_FILTER,
|
||||
@ -38,6 +39,7 @@ import {
|
||||
ERC20BridgeSource,
|
||||
FillData,
|
||||
GenerateOptimizedOrdersOpts,
|
||||
GetMarketOrdersOpts,
|
||||
MarketSideLiquidity,
|
||||
NativeFillData,
|
||||
} from '../src/utils/market_operation_utils/types';
|
||||
@ -66,8 +68,12 @@ const SELL_SOURCES = SELL_SOURCE_FILTER.sources;
|
||||
|
||||
// tslint:disable: custom-no-magic-numbers promise-function-async
|
||||
describe('MarketOperationUtils tests', () => {
|
||||
const CHAIN_ID = 1;
|
||||
const contractAddresses = { ...getContractAddressesForChainOrThrow(CHAIN_ID), multiBridge: NULL_ADDRESS };
|
||||
const CHAIN_ID = ChainId.Mainnet;
|
||||
const contractAddresses = {
|
||||
...getContractAddressesForChainOrThrow(CHAIN_ID),
|
||||
multiBridge: NULL_ADDRESS,
|
||||
...BRIDGE_ADDRESSES_BY_CHAIN[CHAIN_ID],
|
||||
};
|
||||
|
||||
function getMockedQuoteRequestor(
|
||||
type: 'indicative' | 'firm',
|
||||
@ -522,13 +528,15 @@ describe('MarketOperationUtils tests', () => {
|
||||
FILL_AMOUNT,
|
||||
_.times(NUM_SAMPLES, i => DEFAULT_RATES[ERC20BridgeSource.Native][i]),
|
||||
);
|
||||
const DEFAULT_OPTS = {
|
||||
const DEFAULT_OPTS: Partial<GetMarketOrdersOpts> = {
|
||||
numSamples: NUM_SAMPLES,
|
||||
sampleDistributionBase: 1,
|
||||
bridgeSlippage: 0,
|
||||
maxFallbackSlippage: 100,
|
||||
excludedSources: DEFAULT_EXCLUDED,
|
||||
allowFallback: false,
|
||||
gasSchedule: {},
|
||||
feeSchedule: {},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
@ -1428,7 +1436,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
...DEFAULT_OPTS,
|
||||
numSamples: 4,
|
||||
excludedSources: [
|
||||
...DEFAULT_OPTS.excludedSources,
|
||||
...(DEFAULT_OPTS.excludedSources as ERC20BridgeSource[]),
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
ERC20BridgeSource.Bancor,
|
||||
@ -1449,13 +1457,15 @@ describe('MarketOperationUtils tests', () => {
|
||||
FILL_AMOUNT,
|
||||
_.times(NUM_SAMPLES, () => DEFAULT_RATES[ERC20BridgeSource.Native][0]),
|
||||
);
|
||||
const DEFAULT_OPTS = {
|
||||
const DEFAULT_OPTS: Partial<GetMarketOrdersOpts> = {
|
||||
numSamples: NUM_SAMPLES,
|
||||
sampleDistributionBase: 1,
|
||||
bridgeSlippage: 0,
|
||||
maxFallbackSlippage: 100,
|
||||
excludedSources: DEFAULT_EXCLUDED,
|
||||
allowFallback: false,
|
||||
gasSchedule: {},
|
||||
feeSchedule: {},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
@ -1869,7 +1879,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
...DEFAULT_OPTS,
|
||||
numSamples: 4,
|
||||
excludedSources: [
|
||||
...DEFAULT_OPTS.excludedSources,
|
||||
...(DEFAULT_OPTS.excludedSources as ERC20BridgeSource[]),
|
||||
ERC20BridgeSource.Eth2Dai,
|
||||
ERC20BridgeSource.Kyber,
|
||||
],
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ContractFunctionObj } from '@0x/base-contract';
|
||||
import { ContractTxFunctionObj } from '@0x/base-contract';
|
||||
import { constants } from '@0x/contracts-test-utils';
|
||||
import { Order } from '@0x/types';
|
||||
import { BigNumber, hexUtils } from '@0x/utils';
|
||||
@ -82,7 +82,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
this._handlers = handlers;
|
||||
}
|
||||
|
||||
public batchCall(callDatas: string[]): ContractFunctionObj<string[]> {
|
||||
public batchCall(callDatas: string[]): ContractTxFunctionObj<string[]> {
|
||||
return {
|
||||
...super.batchCall(callDatas),
|
||||
callAsync: async (..._callArgs: any[]) => callDatas.map(callData => this._callEncodedFunction(callData)),
|
||||
@ -92,7 +92,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
public getOrderFillableMakerAssetAmounts(
|
||||
orders: Order[],
|
||||
signatures: string[],
|
||||
): ContractFunctionObj<GetOrderFillableAssetAmountResult> {
|
||||
): ContractTxFunctionObj<GetOrderFillableAssetAmountResult> {
|
||||
return this._wrapCall(
|
||||
super.getOrderFillableMakerAssetAmounts,
|
||||
this._handlers.getOrderFillableMakerAssetAmounts,
|
||||
@ -105,7 +105,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
public getOrderFillableTakerAssetAmounts(
|
||||
orders: Order[],
|
||||
signatures: string[],
|
||||
): ContractFunctionObj<GetOrderFillableAssetAmountResult> {
|
||||
): ContractTxFunctionObj<GetOrderFillableAssetAmountResult> {
|
||||
return this._wrapCall(
|
||||
super.getOrderFillableTakerAssetAmounts,
|
||||
this._handlers.getOrderFillableTakerAssetAmounts,
|
||||
@ -120,7 +120,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<[string, BigNumber[]]> {
|
||||
): ContractTxFunctionObj<[string, BigNumber[]]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromKyberNetwork,
|
||||
this._handlers.sampleSellsFromKyberNetwork,
|
||||
@ -135,7 +135,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<BigNumber[]> {
|
||||
): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromEth2Dai,
|
||||
this._handlers.sampleSellsFromEth2Dai,
|
||||
@ -149,7 +149,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<BigNumber[]> {
|
||||
): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromUniswap,
|
||||
this._handlers.sampleSellsFromUniswap,
|
||||
@ -159,7 +159,10 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
);
|
||||
}
|
||||
|
||||
public sampleSellsFromUniswapV2(path: string[], takerAssetAmounts: BigNumber[]): ContractFunctionObj<BigNumber[]> {
|
||||
public sampleSellsFromUniswapV2(
|
||||
path: string[],
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromUniswapV2,
|
||||
this._handlers.sampleSellsFromUniswapV2,
|
||||
@ -173,7 +176,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<[BigNumber[], string]> {
|
||||
): ContractTxFunctionObj<[BigNumber[], string]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromLiquidityProviderRegistry,
|
||||
this._handlers.sampleSellsFromLiquidityProviderRegistry,
|
||||
@ -190,7 +193,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
intermediateToken: string,
|
||||
makerToken: string,
|
||||
takerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<BigNumber[]> {
|
||||
): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleSellsFromMultiBridge,
|
||||
this._handlers.sampleSellsFromMultiBridge,
|
||||
@ -206,7 +209,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
makerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<BigNumber[]> {
|
||||
): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleBuysFromEth2Dai,
|
||||
this._handlers.sampleBuysFromEth2Dai,
|
||||
@ -220,7 +223,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
makerAssetAmounts: BigNumber[],
|
||||
): ContractFunctionObj<BigNumber[]> {
|
||||
): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleBuysFromUniswap,
|
||||
this._handlers.sampleBuysFromUniswap,
|
||||
@ -230,7 +233,7 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
);
|
||||
}
|
||||
|
||||
public sampleBuysFromUniswapV2(path: string[], makerAssetAmounts: BigNumber[]): ContractFunctionObj<BigNumber[]> {
|
||||
public sampleBuysFromUniswapV2(path: string[], makerAssetAmounts: BigNumber[]): ContractTxFunctionObj<BigNumber[]> {
|
||||
return this._wrapCall(
|
||||
super.sampleBuysFromUniswapV2,
|
||||
this._handlers.sampleBuysFromUniswapV2,
|
||||
@ -266,11 +269,11 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
|
||||
}
|
||||
|
||||
private _wrapCall<TArgs extends any[], TResult>(
|
||||
superFn: (this: MockSamplerContract, ...args: TArgs) => ContractFunctionObj<TResult>,
|
||||
superFn: (this: MockSamplerContract, ...args: TArgs) => ContractTxFunctionObj<TResult>,
|
||||
handler?: (this: MockSamplerContract, ...args: TArgs) => TResult,
|
||||
// tslint:disable-next-line: trailing-comma
|
||||
...args: TArgs
|
||||
): ContractFunctionObj<TResult> {
|
||||
): ContractTxFunctionObj<TResult> {
|
||||
return {
|
||||
...superFn.call(this, ...args),
|
||||
callAsync: async (..._callArgs: any[]): Promise<TResult> => {
|
||||
|
@ -7,6 +7,7 @@ export * from '../test/generated-wrappers/approximate_buys';
|
||||
export * from '../test/generated-wrappers/balancer_sampler';
|
||||
export * from '../test/generated-wrappers/curve_sampler';
|
||||
export * from '../test/generated-wrappers/d_o_d_o_sampler';
|
||||
export * from '../test/generated-wrappers/deployment_constants';
|
||||
export * from '../test/generated-wrappers/dummy_liquidity_provider';
|
||||
export * from '../test/generated-wrappers/dummy_liquidity_provider_registry';
|
||||
export * from '../test/generated-wrappers/erc20_bridge_sampler';
|
||||
|
@ -12,6 +12,7 @@
|
||||
"test/generated-artifacts/BalancerSampler.json",
|
||||
"test/generated-artifacts/CurveSampler.json",
|
||||
"test/generated-artifacts/DODOSampler.json",
|
||||
"test/generated-artifacts/DeploymentConstants.json",
|
||||
"test/generated-artifacts/DummyLiquidityProvider.json",
|
||||
"test/generated-artifacts/DummyLiquidityProviderRegistry.json",
|
||||
"test/generated-artifacts/ERC20BridgeSampler.json",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "5.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Moved Bridge addresses into Asset-swapper",
|
||||
"pr": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.12.0",
|
||||
"changes": [
|
||||
|
@ -19,33 +19,19 @@
|
||||
"stakingProxy": "0xa26e80e7dea86279c6d778d702cc413e6cffa777",
|
||||
"devUtils": "0x74134cf88b21383713e096a5ecf59e297dc7f547",
|
||||
"erc20BridgeProxy": "0x8ed95d1746bf1e4dab58d8ed4724f1ef95b20db0",
|
||||
"uniswapBridge": "0x36691c4f426eb8f42f150ebde43069a31cb080ad",
|
||||
"uniswapV2Bridge": "0xdcd6011f4c6b80e470d9487f5871a0cba7c93f48",
|
||||
"erc20BridgeSampler": "0xd8c38704c9937ea3312de29f824b4ad3450a5e61",
|
||||
"kyberBridge": "0xadd97271402590564ddd8ad23cb5317b1fb0fffb",
|
||||
"eth2DaiBridge": "0x991c745401d5b5e469b8c3e2cb02c748f08754f1",
|
||||
"chaiBridge": "0x77c31eba23043b9a72d13470f3a3a311344d7438",
|
||||
"dydxBridge": "0x92af95e37afddac412e5688a9dcc1dd815d4ae53",
|
||||
"godsUnchainedValidator": "0x09a379ef7218bcfd8913faa8b281ebc5a2e0bc04",
|
||||
"broker": "0xd4690a51044db77d91d7aa8f7a3a5ad5da331af0",
|
||||
"chainlinkStopLimit": "0xeb27220f95f364e1d9531992c48613f231839f53",
|
||||
"curveBridge": "0x1796cd592d19e3bcd744fbb025bb61a6d8cb2c09",
|
||||
"maximumGasPrice": "0xe2bfd35306495d11e3c9db0d8de390cda24563cf",
|
||||
"dexForwarderBridge": "0xc47b7094f378e54347e281aab170e8cca69d880a",
|
||||
"multiBridge": "0xc03117a8c9bde203f70aa911cb64a7a0df5ba1e1",
|
||||
"balancerBridge": "0xfe01821ca163844203220cd08e4f2b2fb43ae4e4",
|
||||
"bancorBridge": "0x259897d9699553edbdf8538599242354e957fb94",
|
||||
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
|
||||
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
||||
"exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb",
|
||||
"exchangeProxyTransformerDeployer": "0x39dce47a67ad34344eab877eae3ef1fa2a1d50bb",
|
||||
"exchangeProxyFlashWallet": "0x22f9dcf4647084d6c31b2765f6910cd85c178c18",
|
||||
"mStableBridge": "0x2bf04fcea05f0989a14d9afa37aa376baca6b2b3",
|
||||
"mooniswapBridge": "0x02b7eca484ad960fca3f7709e0b2ac81eec3069c",
|
||||
"sushiswapBridge": "0x47ed0262a0b688dcb836d254c6a2e96b6c48a9f5",
|
||||
"shellBridge": "0x21fb3862eed7911e0f8219a077247b849846728d",
|
||||
"dodoBridge": "0xe9da66965a9344aab2167e6813c03f043cc7a6ca",
|
||||
"creamBridge": "0xb9d4bf2c8dab828f4ffb656acdb6c2b497d44f25",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x68c0bb685099dc7cb5c5ce2b26185945b357383e",
|
||||
"payTakerTransformer": "0x49b9df2c58491764cf40cb052dd4243df63622c7",
|
||||
@ -73,33 +59,19 @@
|
||||
"staking": "0x4af649ffde640ceb34b1afaba3e0bb8e9698cb01",
|
||||
"stakingProxy": "0x6acab4c9c4e3a0c78435fdb5ad1719c95460a668",
|
||||
"erc20BridgeProxy": "0xb344afed348de15eb4a9e180205a2b0739628339",
|
||||
"uniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"uniswapV2Bridge": "0x0000000000000000000000000000000000000000",
|
||||
"eth2DaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
|
||||
"kyberBridge": "0x0000000000000000000000000000000000000000",
|
||||
"chaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dydxBridge": "0x0000000000000000000000000000000000000000",
|
||||
"godsUnchainedValidator": "0xd4690a51044db77d91d7aa8f7a3a5ad5da331af0",
|
||||
"broker": "0x4022e3982f326455f0905de3dbc4449999baf2dc",
|
||||
"chainlinkStopLimit": "0x67a094cf028221ffdd93fc658f963151d05e2a74",
|
||||
"curveBridge": "0x1796cd592d19e3bcd744fbb025bb61a6d8cb2c09",
|
||||
"maximumGasPrice": "0x407b4128e9ecad8769b2332312a9f655cb9f5f3a",
|
||||
"dexForwarderBridge": "0x3261ea1411a1a840aed708896f779e1b837c917e",
|
||||
"multiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"balancerBridge": "0x47697b44bd89051e93b4d5857ba8e024800a74ac",
|
||||
"bancorBridge": "0x0000000000000000000000000000000000000000",
|
||||
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
|
||||
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
||||
"exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb",
|
||||
"exchangeProxyTransformerDeployer": "0x1c9a27658dd303a31205a3b245e8993b92d4d502",
|
||||
"exchangeProxyFlashWallet": "0x22f9dcf4647084d6c31b2765f6910cd85c178c18",
|
||||
"mStableBridge": "0x0000000000000000000000000000000000000000",
|
||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
||||
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
||||
@ -127,33 +99,19 @@
|
||||
"staking": "0x6acab4c9c4e3a0c78435fdb5ad1719c95460a668",
|
||||
"stakingProxy": "0x781ee6683595f823208be6540a279f940e6af196",
|
||||
"erc20BridgeProxy": "0xa2aa4befed748fba27a3be7dfd2c4b2c6db1f49b",
|
||||
"uniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"uniswapV2Bridge": "0x0000000000000000000000000000000000000000",
|
||||
"eth2DaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
|
||||
"kyberBridge": "0x0000000000000000000000000000000000000000",
|
||||
"chaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dydxBridge": "0x0000000000000000000000000000000000000000",
|
||||
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
|
||||
"broker": "0x0dd2d6cabbd8ae7d2fe6840fa597a44b1a7e4747",
|
||||
"chainlinkStopLimit": "0x407b4128e9ecad8769b2332312a9f655cb9f5f3a",
|
||||
"curveBridge": "0x1796cd592d19e3bcd744fbb025bb61a6d8cb2c09",
|
||||
"maximumGasPrice": "0x47697b44bd89051e93b4d5857ba8e024800a74ac",
|
||||
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
|
||||
"multiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"balancerBridge": "0x5d8c9ba74607d2cbc4176882a42d4ace891c1c00",
|
||||
"bancorBridge": "0x0000000000000000000000000000000000000000",
|
||||
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
|
||||
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
||||
"exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb",
|
||||
"exchangeProxyTransformerDeployer": "0x1c9a27658dd303a31205a3b245e8993b92d4d502",
|
||||
"exchangeProxyFlashWallet": "0x22f9dcf4647084d6c31b2765f6910cd85c178c18",
|
||||
"mStableBridge": "0x0000000000000000000000000000000000000000",
|
||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
||||
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
||||
@ -181,33 +139,19 @@
|
||||
"staking": "0x73ea24041e03a012c51a45c307e0ba376af0238c",
|
||||
"stakingProxy": "0xe94cb304b3f515be7c95fedcfa249a84995fd748",
|
||||
"erc20BridgeProxy": "0x3577552c1fb7a44ad76beeb7ab53251668a21f8d",
|
||||
"uniswapBridge": "0x0e85f89f29998df65402391478e5924700c0079d",
|
||||
"uniswapV2Bridge": "0x7b3530a635d099de0534dc27e46cd7c57578c3c8",
|
||||
"eth2DaiBridge": "0x2d47147429b474d2e4f83e658015858a1312ed5b",
|
||||
"erc20BridgeSampler": "0xcf9e66851f274aa4721e54526117876d90d51aa1",
|
||||
"kyberBridge": "0xaecfa25920f892b6eb496e1f6e84037f59da7f44",
|
||||
"chaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dydxBridge": "0xc213707de0454008758071c2edc1365621b8a5c5",
|
||||
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
|
||||
"broker": "0xcdeb6d90ee7c96b4c713f7bb4f8604981f7ebe9d",
|
||||
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
|
||||
"curveBridge": "0x81c0ab53a7352d2e97f682a37cba44e54647eefb",
|
||||
"maximumGasPrice": "0x67a094cf028221ffdd93fc658f963151d05e2a74",
|
||||
"dexForwarderBridge": "0x985d1a95c6a86a3bf85c4d425af984abceaf01de",
|
||||
"multiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"balancerBridge": "0x407b4128e9ecad8769b2332312a9f655cb9f5f3a",
|
||||
"bancorBridge": "0x0000000000000000000000000000000000000000",
|
||||
"exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e",
|
||||
"exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff",
|
||||
"exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb",
|
||||
"exchangeProxyTransformerDeployer": "0x1b62de2dbb5e7aa519e9c442721ecef75702807f",
|
||||
"exchangeProxyFlashWallet": "0x22f9dcf4647084d6c31b2765f6910cd85c178c18",
|
||||
"mStableBridge": "0x0000000000000000000000000000000000000000",
|
||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x9ce35b5ee9e710535e3988e3f8731d9ca9dba17d",
|
||||
"payTakerTransformer": "0x5a53e7b02a83aa9f60ccf4e424f0442c255bc977",
|
||||
@ -235,33 +179,19 @@
|
||||
"zrxVault": "0xf23276778860e420acfc18ebeebf7e829b06965c",
|
||||
"staking": "0x8a063452f7df2614db1bca3a85ef35da40cf0835",
|
||||
"stakingProxy": "0x59adefa01843c627ba5d6aa350292b4b7ccae67a",
|
||||
"uniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"uniswapV2Bridge": "0x0000000000000000000000000000000000000000",
|
||||
"eth2DaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
|
||||
"kyberBridge": "0x0000000000000000000000000000000000000000",
|
||||
"chaiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dydxBridge": "0x0000000000000000000000000000000000000000",
|
||||
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
|
||||
"broker": "0x0000000000000000000000000000000000000000",
|
||||
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
|
||||
"curveBridge": "0x0000000000000000000000000000000000000000",
|
||||
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
|
||||
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
|
||||
"multiBridge": "0x0000000000000000000000000000000000000000",
|
||||
"balancerBridge": "0x0000000000000000000000000000000000000000",
|
||||
"bancorBridge": "0x0000000000000000000000000000000000000000",
|
||||
"exchangeProxyGovernor": "0x0000000000000000000000000000000000000000",
|
||||
"exchangeProxy": "0x5315e44798395d4a952530d131249fe00f554565",
|
||||
"exchangeProxyAllowanceTarget": "0x8362c3ebd90041b30ec45908332e592721642637",
|
||||
"exchangeProxyTransformerDeployer": "0x5409ed021d9299bf6814279a6a1411a7e866a631",
|
||||
"exchangeProxyFlashWallet": "0xb9682a8e7920b431f1d412b8510f0077410c8faa",
|
||||
"mStableBridge": "0x0000000000000000000000000000000000000000",
|
||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0xc6b0d3c45a6b5092808196cb00df5c357d55e1d5",
|
||||
"payTakerTransformer": "0x7209185959d7227fb77274e1e88151d7c4c368d3",
|
||||
|
@ -21,32 +21,18 @@ export interface ContractAddresses {
|
||||
stakingProxy: string;
|
||||
erc20BridgeProxy: string;
|
||||
erc20BridgeSampler: string;
|
||||
uniswapBridge: string;
|
||||
uniswapV2Bridge: string;
|
||||
eth2DaiBridge: string;
|
||||
kyberBridge: string;
|
||||
chaiBridge: string;
|
||||
dydxBridge: string;
|
||||
curveBridge: string;
|
||||
godsUnchainedValidator: string;
|
||||
broker: string;
|
||||
chainlinkStopLimit: string;
|
||||
maximumGasPrice: string;
|
||||
dexForwarderBridge: string;
|
||||
multiBridge: string;
|
||||
balancerBridge: string;
|
||||
bancorBridge: string;
|
||||
exchangeProxyGovernor: string;
|
||||
exchangeProxy: string;
|
||||
exchangeProxyAllowanceTarget: string;
|
||||
exchangeProxyTransformerDeployer: string;
|
||||
exchangeProxyFlashWallet: string;
|
||||
mStableBridge: string;
|
||||
mooniswapBridge: string;
|
||||
sushiswapBridge: string;
|
||||
shellBridge: string;
|
||||
dodoBridge: string;
|
||||
creamBridge: string;
|
||||
transformers: {
|
||||
wethTransformer: string;
|
||||
payTakerTransformer: string;
|
||||
|
@ -317,16 +317,22 @@ export async function runMigrationsAsync(
|
||||
mooniswapBridge: NULL_ADDRESS,
|
||||
mStableBridge: NULL_ADDRESS,
|
||||
oasisBridge: NULL_ADDRESS,
|
||||
swerveBridge: NULL_ADDRESS,
|
||||
sushiswapBridge: 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,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
shell: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
dodoHelper: NULL_ADDRESS,
|
||||
snowSwapBridge: NULL_ADDRESS,
|
||||
weth: etherToken.address,
|
||||
},
|
||||
);
|
||||
@ -384,29 +390,15 @@ export async function runMigrationsAsync(
|
||||
zrxVault: zrxVault.address,
|
||||
staking: stakingLogic.address,
|
||||
stakingProxy: stakingProxy.address,
|
||||
uniswapBridge: NULL_ADDRESS,
|
||||
eth2DaiBridge: NULL_ADDRESS,
|
||||
kyberBridge: NULL_ADDRESS,
|
||||
erc20BridgeSampler: NULL_ADDRESS,
|
||||
chaiBridge: NULL_ADDRESS,
|
||||
dydxBridge: NULL_ADDRESS,
|
||||
curveBridge: NULL_ADDRESS,
|
||||
uniswapV2Bridge: NULL_ADDRESS,
|
||||
godsUnchainedValidator: NULL_ADDRESS,
|
||||
broker: NULL_ADDRESS,
|
||||
chainlinkStopLimit: NULL_ADDRESS,
|
||||
maximumGasPrice: NULL_ADDRESS,
|
||||
dexForwarderBridge: NULL_ADDRESS,
|
||||
multiBridge: NULL_ADDRESS,
|
||||
balancerBridge: NULL_ADDRESS,
|
||||
bancorBridge: NULL_ADDRESS,
|
||||
exchangeProxyGovernor: NULL_ADDRESS,
|
||||
mStableBridge: NULL_ADDRESS,
|
||||
mooniswapBridge: NULL_ADDRESS,
|
||||
sushiswapBridge: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
exchangeProxy: exchangeProxy.address,
|
||||
exchangeProxyAllowanceTarget: exchangeProxyAllowanceTargetAddress,
|
||||
exchangeProxyTransformerDeployer: txDefaults.from,
|
||||
|
Loading…
x
Reference in New Issue
Block a user