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:
		| @@ -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; | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user