diff --git a/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapEthForERC20OnUniswap.sol b/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapEthForERC20OnUniswap.sol index d91c653459..1c7ffb9561 100644 --- a/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapEthForERC20OnUniswap.sol +++ b/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapEthForERC20OnUniswap.sol @@ -12,7 +12,6 @@ import "src/transformers/WethTransformer.sol"; import "src/transformers/FillQuoteTransformer.sol"; import "src/transformers/bridges/BridgeProtocols.sol"; import "src/features/OtcOrdersFeature.sol"; -import "samplers/UniswapV2Sampler.sol"; contract SwapEthForERC20OnUniswap is Test, ForkUtils, TestUtils { /*////////////////////////////////////////////////////////////// @@ -178,14 +177,12 @@ contract SwapEthForERC20OnUniswap is Test, ForkUtils, TestUtils { address makerToken, address router ) public returns (uint256 makerTokenAmounts) { - UniswapV2Sampler sampler = new UniswapV2Sampler(); - vm.label(address(sampler), "UniswapV2Sampler"); address[] memory path = new address[](2); path[0] = address(takerToken); path[1] = address(makerToken); uint256[] memory amounts = new uint256[](1); amounts[0] = amount; - uint256 out = sampler.sampleSellsFromUniswapV2(router, path, amounts)[0]; + uint256 out = sampleSellsFromUniswapV2(router, path, amounts)[0]; log_string(" Sampling Uniswap for tokens"); log_named_address(" ", takerToken); diff --git a/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapNativeToERC20RFQTv2.sol b/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapNativeToERC20RFQTv2.sol index 78d01623e6..055cc19b3e 100644 --- a/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapNativeToERC20RFQTv2.sol +++ b/contracts/zero-ex/contracts/test/foundry/forkedTests/SwapNativeToERC20RFQTv2.sol @@ -12,7 +12,6 @@ import "src/transformers/WethTransformer.sol"; import "src/transformers/FillQuoteTransformer.sol"; import "src/transformers/bridges/BridgeProtocols.sol"; import "src/features/OtcOrdersFeature.sol"; -import "samplers/UniswapV2Sampler.sol"; contract SwapNativeToERC20RFQTv2 is Test, ForkUtils, TestUtils { /*////////////////////////////////////////////////////////////// diff --git a/contracts/zero-ex/contracts/test/foundry/utils/ForkUtils.sol b/contracts/zero-ex/contracts/test/foundry/utils/ForkUtils.sol index 80bd9afac0..39f73f4aa4 100644 --- a/contracts/zero-ex/contracts/test/foundry/utils/ForkUtils.sol +++ b/contracts/zero-ex/contracts/test/foundry/utils/ForkUtils.sol @@ -77,6 +77,12 @@ interface IFQT { function bridgeAdapter() external returns (address); } +interface IUniswapV2Router01 { + function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); + + function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); +} + contract ForkUtils is Test { using stdJson for string; @@ -110,6 +116,8 @@ contract ForkUtils is Test { string tokensJson; string sourcesJson; + uint256 private constant UNISWAPV2_CALL_GAS = 150e3; // 150k + //utility mapping to get chainId by name mapping(string => string) public chainsByChainId; //utility mapping to get indexingChainId by Chain @@ -266,6 +274,58 @@ contract ForkUtils is Test { } } + function sampleSellsFromUniswapV2( + address router, + address[] memory path, + uint256[] memory takerTokenAmounts + ) public view returns (uint256[] memory makerTokenAmounts) { + uint256 numSamples = takerTokenAmounts.length; + makerTokenAmounts = new uint256[](numSamples); + for (uint256 i = 0; i < numSamples; i++) { + try IUniswapV2Router01(router).getAmountsOut{gas: UNISWAPV2_CALL_GAS}(takerTokenAmounts[i], path) returns ( + uint256[] memory amounts + ) { + makerTokenAmounts[i] = amounts[path.length - 1]; + // Break early if there are 0 amounts + if (makerTokenAmounts[i] == 0) { + break; + } + } catch (bytes memory) { + // Swallow failures, leaving all results as zero. + break; + } + } + } + + /// @dev Sample buy quotes from UniswapV2. + /// @param router Router to look up tokens and amounts + /// @param path Token route. Should be takerToken -> makerToken. + /// @param makerTokenAmounts Maker token buy amount for each sample. + /// @return takerTokenAmounts Taker amounts sold at each maker token + /// amount. + function sampleBuysFromUniswapV2( + address router, + address[] memory path, + uint256[] memory makerTokenAmounts + ) public view returns (uint256[] memory takerTokenAmounts) { + uint256 numSamples = makerTokenAmounts.length; + takerTokenAmounts = new uint256[](numSamples); + for (uint256 i = 0; i < numSamples; i++) { + try IUniswapV2Router01(router).getAmountsIn{gas: UNISWAPV2_CALL_GAS}(makerTokenAmounts[i], path) returns ( + uint256[] memory amounts + ) { + takerTokenAmounts[i] = amounts[0]; + // Break early if there are 0 amounts + if (takerTokenAmounts[i] == 0) { + break; + } + } catch (bytes memory) { + // Swallow failures, leaving all results as zero. + break; + } + } + } + modifier onlyForked() { if (block.number >= 15000000) { _; diff --git a/contracts/zero-ex/contracts/test/samplers/ApproximateBuys.sol b/contracts/zero-ex/contracts/test/samplers/ApproximateBuys.sol deleted file mode 100644 index d9a2536047..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/ApproximateBuys.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; - -contract ApproximateBuys { - /// @dev Information computing buy quotes for sources that do not have native - /// buy quote support. - struct ApproximateBuyQuoteOpts { - // Arbitrary maker token data to pass to `getSellQuoteCallback`. - bytes makerTokenData; - // Arbitrary taker token data to pass to `getSellQuoteCallback`. - bytes takerTokenData; - // Callback to retrieve a sell quote. - function(bytes memory, bytes memory, uint256) internal view returns (uint256) getSellQuoteCallback; - } - - uint256 private constant ONE_HUNDED_PERCENT_BPS = 1e4; - /// @dev Maximum approximate (positive) error rate when approximating a buy quote. - uint256 private constant APPROXIMATE_BUY_TARGET_EPSILON_BPS = 0.0005e4; - /// @dev Maximum iterations to perform when approximating a buy quote. - uint256 private constant APPROXIMATE_BUY_MAX_ITERATIONS = 5; - - function _sampleApproximateBuys( - ApproximateBuyQuoteOpts memory opts, - uint256[] memory makerTokenAmounts - ) internal view returns (uint256[] memory takerTokenAmounts) { - takerTokenAmounts = new uint256[](makerTokenAmounts.length); - if (makerTokenAmounts.length == 0) { - return takerTokenAmounts; - } - - uint256 sellAmount = opts.getSellQuoteCallback(opts.makerTokenData, opts.takerTokenData, makerTokenAmounts[0]); - if (sellAmount == 0) { - return takerTokenAmounts; - } - - uint256 buyAmount = opts.getSellQuoteCallback(opts.takerTokenData, opts.makerTokenData, sellAmount); - if (buyAmount == 0) { - return takerTokenAmounts; - } - - for (uint256 i = 0; i < makerTokenAmounts.length; i++) { - uint256 eps = 0; - for (uint256 iter = 0; iter < APPROXIMATE_BUY_MAX_ITERATIONS; iter++) { - // adjustedSellAmount = previousSellAmount * (target/actual) * JUMP_MULTIPLIER - sellAmount = _safeGetPartialAmountCeil(makerTokenAmounts[i], buyAmount, sellAmount); - if (sellAmount == 0) { - break; - } - sellAmount = _safeGetPartialAmountCeil( - (ONE_HUNDED_PERCENT_BPS + APPROXIMATE_BUY_TARGET_EPSILON_BPS), - ONE_HUNDED_PERCENT_BPS, - sellAmount - ); - if (sellAmount == 0) { - break; - } - uint256 _buyAmount = opts.getSellQuoteCallback(opts.takerTokenData, opts.makerTokenData, sellAmount); - if (_buyAmount == 0) { - break; - } - // We re-use buyAmount next iteration, only assign if it is - // non zero - buyAmount = _buyAmount; - // If we've reached our goal, exit early - if (buyAmount >= makerTokenAmounts[i]) { - eps = ((buyAmount - makerTokenAmounts[i]) * ONE_HUNDED_PERCENT_BPS) / makerTokenAmounts[i]; - if (eps <= APPROXIMATE_BUY_TARGET_EPSILON_BPS) { - break; - } - } - } - if (eps == 0 || eps > APPROXIMATE_BUY_TARGET_EPSILON_BPS) { - break; - } - // We do our best to close in on the requested amount, but we can either over buy or under buy and exit - // if we hit a max iteration limit - // We scale the sell amount to get the approximate target - takerTokenAmounts[i] = _safeGetPartialAmountCeil(makerTokenAmounts[i], buyAmount, sellAmount); - } - } - - function _safeGetPartialAmountCeil( - uint256 numerator, - uint256 denominator, - uint256 target - ) internal view returns (uint256 partialAmount) { - if (numerator == 0 || target == 0 || denominator == 0) return 0; - uint256 c = numerator * target; - if (c / numerator != target) return 0; - return (c + (denominator - 1)) / denominator; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BalanceChecker.sol b/contracts/zero-ex/contracts/test/samplers/BalanceChecker.sol deleted file mode 100644 index a6e26b510e..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BalanceChecker.sol +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -// ERC20 contract interface -abstract contract IToken { - /// @dev Query the balance of owner - /// @param _owner The address from which the balance will be retrieved - /// @return Balance of owner - function balanceOf(address _owner) public view virtual returns (uint256); - - /// @param _owner The address of the account owning tokens - /// @param _spender The address of the account able to transfer the tokens - /// @return Amount of remaining tokens allowed to spent - function allowance(address _owner, address _spender) public view virtual returns (uint256); -} - -contract BalanceChecker { - /* - Check the token balances of wallet-token pairs. - Pass 0xeee... as a "token" address to get ETH balance. - Possible error throws: - - extremely large arrays for user and or tokens (gas cost too high) - - Returns a one-dimensional that's user.length long. - */ - function balances(address[] calldata users, address[] calldata tokens) external view returns (uint256[] memory) { - // make sure the users array and tokens array are of equal length - require(users.length == tokens.length, "users array is a different length than the tokens array"); - - uint256[] memory addrBalances = new uint256[](users.length); - - for (uint i = 0; i < users.length; i++) { - if (tokens[i] != address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)) { - addrBalances[i] = IToken(tokens[i]).balanceOf(users[i]); - } else { - addrBalances[i] = users[i].balance; // ETH balance - } - } - - return addrBalances; - } - - /* - Check the token balances of wallet-token pairs with a spender contract for an allowance check. - Pass 0xeee... as a "token" address to get ETH balance. - Possible error throws: - - extremely large arrays for user and or tokens (gas cost too high) - - Returns a one-dimensional that's user.length long. It is the lesser of balance and allowance - */ - function getMinOfBalancesOrAllowances( - address[] calldata users, - address[] calldata tokens, - address spender - ) external view returns (uint256[] memory) { - // make sure the users array and tokens array are of equal length - require(users.length == tokens.length, "users array is a different length than the tokens array"); - - uint256[] memory addrBalances = new uint256[](users.length); - - for (uint i = 0; i < users.length; i++) { - if (tokens[i] != address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)) { - uint256 balance; - uint256 allowance; - balance = IToken(tokens[i]).balanceOf(users[i]); - allowance = IToken(tokens[i]).allowance(users[i], spender); - if (allowance < balance) { - addrBalances[i] = allowance; - } else { - addrBalances[i] = balance; - } - } else { - addrBalances[i] = users[i].balance; // ETH balance - } - } - - return addrBalances; - } - - /* - Check the allowances of an array of owner-spender-tokens - - Returns 0 for 0xeee... (ETH) - Possible error throws: - - extremely large arrays for user and or tokens (gas cost too high) - - Returns a one-dimensional array that's owners.length long. - */ - function allowances( - address[] calldata owners, - address[] calldata spenders, - address[] calldata tokens - ) external view returns (uint256[] memory) { - // make sure the arrays are all of equal length - require(owners.length == spenders.length, "all arrays must be of equal length"); - require(owners.length == tokens.length, "all arrays must be of equal length"); - - uint256[] memory addrAllowances = new uint256[](owners.length); - - for (uint i = 0; i < owners.length; i++) { - if (tokens[i] != address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)) { - addrAllowances[i] = IToken(tokens[i]).allowance(owners[i], spenders[i]); - } else { - // ETH - addrAllowances[i] = 0; - } - } - - return addrAllowances; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BalancerSampler.sol b/contracts/zero-ex/contracts/test/samplers/BalancerSampler.sol deleted file mode 100644 index b3d30625bb..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BalancerSampler.sol +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IBalancer.sol"; - -contract BalancerSampler { - /// @dev Base gas limit for Balancer calls. - uint256 private constant BALANCER_CALL_GAS = 300e3; // 300k - - // Balancer math constants - // https://github.com/balancer-labs/balancer-core/blob/master/contracts/BConst.sol - uint256 private constant BONE = 10 ** 18; - uint256 private constant MAX_IN_RATIO = BONE / 2; - uint256 private constant MAX_OUT_RATIO = (BONE / 3) + 1 wei; - - struct BalancerState { - uint256 takerTokenBalance; - uint256 makerTokenBalance; - uint256 takerTokenWeight; - uint256 makerTokenWeight; - uint256 swapFee; - } - - /// @dev Sample sell quotes from Balancer. - /// @param poolAddress Address of the Balancer pool to query. - /// @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 makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromBalancer( - address poolAddress, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - IBalancer pool = IBalancer(poolAddress); - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - if (!pool.isBound(takerToken) || !pool.isBound(makerToken)) { - return makerTokenAmounts; - } - - BalancerState memory poolState; - poolState.takerTokenBalance = pool.getBalance(takerToken); - poolState.makerTokenBalance = pool.getBalance(makerToken); - poolState.takerTokenWeight = pool.getDenormalizedWeight(takerToken); - poolState.makerTokenWeight = pool.getDenormalizedWeight(makerToken); - poolState.swapFee = pool.getSwapFee(); - - for (uint256 i = 0; i < numSamples; i++) { - // Handles this revert scenario: - // https://github.com/balancer-labs/balancer-core/blob/master/contracts/BPool.sol#L443 - if (takerTokenAmounts[i] > _bmul(poolState.takerTokenBalance, MAX_IN_RATIO)) { - break; - } - try - pool.calcOutGivenIn{gas: BALANCER_CALL_GAS}( - poolState.takerTokenBalance, - poolState.takerTokenWeight, - poolState.makerTokenBalance, - poolState.makerTokenWeight, - takerTokenAmounts[i], - poolState.swapFee - ) - returns (uint256 amount) { - makerTokenAmounts[i] = amount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Sample buy quotes from Balancer. - /// @param poolAddress Address of the Balancer pool to query. - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromBalancer( - address poolAddress, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - IBalancer pool = IBalancer(poolAddress); - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - if (!pool.isBound(takerToken) || !pool.isBound(makerToken)) { - return takerTokenAmounts; - } - - BalancerState memory poolState; - poolState.takerTokenBalance = pool.getBalance(takerToken); - poolState.makerTokenBalance = pool.getBalance(makerToken); - poolState.takerTokenWeight = pool.getDenormalizedWeight(takerToken); - poolState.makerTokenWeight = pool.getDenormalizedWeight(makerToken); - poolState.swapFee = pool.getSwapFee(); - - for (uint256 i = 0; i < numSamples; i++) { - // Handles this revert scenario: - // https://github.com/balancer-labs/balancer-core/blob/master/contracts/BPool.sol#L505 - if (makerTokenAmounts[i] > _bmul(poolState.makerTokenBalance, MAX_OUT_RATIO)) { - break; - } - try - pool.calcInGivenOut{gas: BALANCER_CALL_GAS}( - poolState.takerTokenBalance, - poolState.takerTokenWeight, - poolState.makerTokenBalance, - poolState.makerTokenWeight, - makerTokenAmounts[i], - poolState.swapFee - ) - returns (uint256 amount) { - // Handles this revert scenario: - // https://github.com/balancer-labs/balancer-core/blob/master/contracts/BPool.sol#L443 - if (amount > _bmul(poolState.takerTokenBalance, MAX_IN_RATIO)) { - break; - } - - takerTokenAmounts[i] = amount; - // Break early if there are 0 amounts - if (takerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Hacked version of Balancer's `bmul` function, returning 0 instead - /// of reverting. - /// https://github.com/balancer-labs/balancer-core/blob/master/contracts/BNum.sol#L63-L73 - /// @param a The first operand. - /// @param b The second operand. - /// @param c The result of the multiplication, or 0 if `bmul` would've reverted. - function _bmul(uint256 a, uint256 b) private pure returns (uint256 c) { - uint c0 = a * b; - if (a != 0 && c0 / a != b) { - return 0; - } - uint c1 = c0 + (BONE / 2); - if (c1 < c0) { - return 0; - } - uint c2 = c1 / BONE; - return c2; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BalancerV2BatchSampler.sol b/contracts/zero-ex/contracts/test/samplers/BalancerV2BatchSampler.sol deleted file mode 100644 index 7db364e330..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BalancerV2BatchSampler.sol +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./interfaces/IBalancerV2Vault.sol"; -import "./BalancerV2Common.sol"; - -contract BalancerV2BatchSampler is BalancerV2Common { - // Replaces amount for first step with each takerTokenAmount and calls queryBatchSwap using supplied steps - /// @dev Sample sell quotes from Balancer V2 supporting multihops. - /// @param swapSteps Array of swap steps (can be >= 1). - /// @param swapAssets Array of token address for swaps. - /// @param takerTokenAmounts Taker token sell amount for each sample. - function sampleMultihopSellsFromBalancerV2( - IBalancerV2Vault vault, - IBalancerV2Vault.BatchSwapStep[] memory swapSteps, - address[] memory swapAssets, - uint256[] memory takerTokenAmounts - ) public returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - IBalancerV2Vault.FundManagement memory swapFunds = _createSwapFunds(); - - for (uint256 i = 0; i < numSamples; i++) { - swapSteps[0].amount = takerTokenAmounts[i]; - try - // For sells we specify the takerToken which is what the vault will receive from the trade - vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_IN, swapSteps, swapAssets, swapFunds) - returns ( - // amounts represent pool balance deltas from the swap (incoming balance, outgoing balance) - int256[] memory amounts - ) { - // Outgoing balance is negative so we need to flip the sign - // Note - queryBatchSwap will return a delta for each token in the assets array and last asset should be tokenOut - int256 amountOutFromPool = amounts[amounts.length - 1] * -1; - if (amountOutFromPool <= 0) { - break; - } - makerTokenAmounts[i] = uint256(amountOutFromPool); - } catch { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - // Replaces amount for first step with each makerTokenAmount and calls queryBatchSwap using supplied steps - /// @dev Sample buy quotes from Balancer V2 supporting multihops. - /// @param swapSteps Array of swap steps (can be >= 1). - /// @param swapAssets Array of token address for swaps. - /// @param makerTokenAmounts Maker token buy amount for each sample. - function sampleMultihopBuysFromBalancerV2( - IBalancerV2Vault vault, - IBalancerV2Vault.BatchSwapStep[] memory swapSteps, - address[] memory swapAssets, - uint256[] memory makerTokenAmounts - ) public returns (uint256[] memory takerTokenAmounts) { - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - IBalancerV2Vault.FundManagement memory swapFunds = _createSwapFunds(); - - for (uint256 i = 0; i < numSamples; i++) { - swapSteps[0].amount = makerTokenAmounts[i]; - try - // Uses GIVEN_OUT type for Buy - vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_OUT, swapSteps, swapAssets, swapFunds) - returns ( - // amounts represent pool balance deltas from the swap (incoming balance, outgoing balance) - int256[] memory amounts - ) { - int256 amountIntoPool = amounts[0]; - if (amountIntoPool <= 0) { - break; - } - takerTokenAmounts[i] = uint256(amountIntoPool); - } catch { - // Swallow failures, leaving all results as zero. - break; - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BalancerV2Common.sol b/contracts/zero-ex/contracts/test/samplers/BalancerV2Common.sol deleted file mode 100644 index 53b62f36bf..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BalancerV2Common.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./interfaces/IBalancerV2Vault.sol"; - -contract BalancerV2Common { - function _createSwapFunds() internal view returns (IBalancerV2Vault.FundManagement memory) { - return - IBalancerV2Vault.FundManagement({ - sender: address(this), - fromInternalBalance: false, - recipient: payable(address(this)), - toInternalBalance: false - }); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BalancerV2Sampler.sol b/contracts/zero-ex/contracts/test/samplers/BalancerV2Sampler.sol deleted file mode 100644 index ec1e6f993f..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BalancerV2Sampler.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./SamplerUtils.sol"; -import "./interfaces/IBalancerV2Vault.sol"; -import "./BalancerV2Common.sol"; - -contract BalancerV2Sampler is SamplerUtils, BalancerV2Common { - /// @dev Sample sell quotes from Balancer V2. - /// @param poolInfo Struct with pool related data - /// @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 makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromBalancerV2( - IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public returns (uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault); - address[] memory swapAssets = new address[](2); - swapAssets[0] = takerToken; - swapAssets[1] = makerToken; - - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - IBalancerV2Vault.FundManagement memory swapFunds = _createSwapFunds(); - - for (uint256 i = 0; i < numSamples; i++) { - IBalancerV2Vault.BatchSwapStep[] memory swapSteps = _createSwapSteps(poolInfo, takerTokenAmounts[i]); - - try - // For sells we specify the takerToken which is what the vault will receive from the trade - vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_IN, swapSteps, swapAssets, swapFunds) - returns ( - // amounts represent pool balance deltas from the swap (incoming balance, outgoing balance) - int256[] memory amounts - ) { - // Outgoing balance is negative so we need to flip the sign - int256 amountOutFromPool = amounts[amounts.length - 1] * -1; - if (amountOutFromPool <= 0) { - break; - } - makerTokenAmounts[i] = uint256(amountOutFromPool); - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Sample buy quotes from Balancer V2. - /// @param poolInfo Struct with pool related data - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromBalancerV2( - IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public returns (uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - IBalancerV2Vault vault = IBalancerV2Vault(poolInfo.vault); - address[] memory swapAssets = new address[](2); - swapAssets[0] = takerToken; - swapAssets[1] = makerToken; - - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - IBalancerV2Vault.FundManagement memory swapFunds = _createSwapFunds(); - - for (uint256 i = 0; i < numSamples; i++) { - IBalancerV2Vault.BatchSwapStep[] memory swapSteps = _createSwapSteps(poolInfo, makerTokenAmounts[i]); - - try - // For buys we specify the makerToken which is what taker will receive from the trade - vault.queryBatchSwap(IBalancerV2Vault.SwapKind.GIVEN_OUT, swapSteps, swapAssets, swapFunds) - returns (int256[] memory amounts) { - int256 amountIntoPool = amounts[0]; - if (amountIntoPool <= 0) { - break; - } - takerTokenAmounts[i] = uint256(amountIntoPool); - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - function _createSwapSteps( - IBalancerV2Vault.BalancerV2PoolInfo memory poolInfo, - uint256 amount - ) private pure returns (IBalancerV2Vault.BatchSwapStep[] memory) { - IBalancerV2Vault.BatchSwapStep[] memory swapSteps = new IBalancerV2Vault.BatchSwapStep[](1); - swapSteps[0] = IBalancerV2Vault.BatchSwapStep({ - poolId: poolInfo.poolId, - assetInIndex: 0, - assetOutIndex: 1, - amount: amount, - userData: "" - }); - - return swapSteps; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BancorSampler.sol b/contracts/zero-ex/contracts/test/samplers/BancorSampler.sol deleted file mode 100644 index 9e2f5d2c7d..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BancorSampler.sol +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IBancor.sol"; - -contract BancorSampler { - /// @dev Base gas limit for Bancor calls. - uint256 private constant BANCOR_CALL_GAS = 300e3; // 300k - - struct BancorSamplerOpts { - IBancorRegistry registry; - address[][] paths; - } - - /// @dev Sample sell quotes from Bancor. - /// @param opts BancorSamplerOpts The Bancor registry contract address and paths - /// @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 bancorNetwork the Bancor Network address - /// @return path the selected conversion path from bancor - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromBancor( - BancorSamplerOpts memory opts, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (address bancorNetwork, address[] memory path, uint256[] memory makerTokenAmounts) { - if (opts.paths.length == 0) { - return (bancorNetwork, path, makerTokenAmounts); - } - (bancorNetwork, path) = _findBestPath(opts, takerToken, makerToken, takerTokenAmounts); - makerTokenAmounts = new uint256[](takerTokenAmounts.length); - - for (uint256 i = 0; i < makerTokenAmounts.length; i++) { - try IBancorNetwork(bancorNetwork).rateByPath{gas: BANCOR_CALL_GAS}(path, takerTokenAmounts[i]) returns ( - uint256 amount - ) { - makerTokenAmounts[i] = amount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch { - // Swallow failures, leaving all results as zero. - break; - } - } - return (bancorNetwork, path, makerTokenAmounts); - } - - /// @dev Sample buy quotes from Bancor. Unimplemented - /// @param opts BancorSamplerOpts The Bancor registry contract address and paths - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return bancorNetwork the Bancor Network address - /// @return path the selected conversion path from bancor - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromBancor( - BancorSamplerOpts memory opts, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (address bancorNetwork, address[] memory path, uint256[] memory takerTokenAmounts) {} - - function _findBestPath( - BancorSamplerOpts memory opts, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) internal view returns (address bancorNetwork, address[] memory path) { - bancorNetwork = opts.registry.getAddress(opts.registry.BANCOR_NETWORK()); - if (opts.paths.length == 0) { - return (bancorNetwork, path); - } - uint256 maxBoughtAmount = 0; - // Find the best path by selling the largest taker amount - for (uint256 i = 0; i < opts.paths.length; i++) { - if (opts.paths[i].length < 2) { - continue; - } - - try - IBancorNetwork(bancorNetwork).rateByPath{gas: BANCOR_CALL_GAS}( - opts.paths[i], - takerTokenAmounts[takerTokenAmounts.length - 1] - ) - returns (uint256 amount) { - if (amount > maxBoughtAmount) { - maxBoughtAmount = amount; - path = opts.paths[i]; - } - } catch { - // Swallow failures, leaving all results as zero. - continue; - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/BancorV3Sampler.sol b/contracts/zero-ex/contracts/test/samplers/BancorV3Sampler.sol deleted file mode 100644 index 58545ed25a..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/BancorV3Sampler.sol +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2022 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; -pragma experimental ABIEncoderV2; - -import "./interfaces/IBancorV3.sol"; - -contract BancorV3Sampler { - /// @dev Gas limit for BancorV3 calls. - uint256 private constant BancorV3_CALL_GAS = 150e3; // 150k - - address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; - - /// @dev Sample sell quotes from BancorV3. - /// @param weth The WETH contract address - /// @param router Router to look up tokens and amounts - /// @param path Token route. Should be takerToken -> makerToken - /// @param takerTokenAmounts Taker token sell amount for each sample. - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromBancorV3( - address weth, - address router, - address[] memory path, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - if (path[0] == weth) { - path[0] = ETH; - } - if (path[1] == weth) { - path[1] = ETH; - } - - for (uint256 i = 0; i < numSamples; i++) { - try IBancorV3(router).tradeOutputBySourceAmount(path[0], path[1], takerTokenAmounts[i]) returns ( - uint256 amount - ) { - makerTokenAmounts[i] = amount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Sample buy quotes from BancorV3. - /// @param weth The WETH contract address - /// @param router Router to look up tokens and amounts - /// @param path Token route. Should be takerToken -> makerToken. - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromBancorV3( - address weth, - address router, - address[] memory path, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - - if (path[0] == weth) { - path[0] = ETH; - } - if (path[1] == weth) { - path[1] = ETH; - } - - for (uint256 i = 0; i < numSamples; i++) { - try IBancorV3(router).tradeInputByTargetAmount(path[0], path[1], makerTokenAmounts[i]) returns ( - uint256 amount - ) { - takerTokenAmounts[i] = amount; - // Break early if there are 0 amounts - if (takerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/CompoundSampler.sol b/contracts/zero-ex/contracts/test/samplers/CompoundSampler.sol deleted file mode 100644 index ab1f385240..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/CompoundSampler.sol +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./SamplerUtils.sol"; -import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; - -// Minimal CToken interface -interface ICToken { - function mint(uint mintAmount) external returns (uint); - - function redeem(uint redeemTokens) external returns (uint); - - function redeemUnderlying(uint redeemAmount) external returns (uint); - - function exchangeRateStored() external view returns (uint); - - function decimals() external view returns (uint8); -} - -contract CompoundSampler is SamplerUtils { - uint256 private constant EXCHANGE_RATE_SCALE = 1e10; - - function sampleSellsFromCompound( - ICToken cToken, - IERC20TokenV06 takerToken, - IERC20TokenV06 makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - // Exchange rate is scaled by 1 * 10^(18 - 8 + Underlying Token Decimals - uint256 exchangeRate = cToken.exchangeRateStored(); - uint256 cTokenDecimals = uint256(cToken.decimals()); - - if (address(makerToken) == address(cToken)) { - // mint - for (uint256 i = 0; i < numSamples; i++) { - makerTokenAmounts[i] = - (takerTokenAmounts[i] * EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals) / - exchangeRate; - } - } else if (address(takerToken) == address(cToken)) { - // redeem - for (uint256 i = 0; i < numSamples; i++) { - makerTokenAmounts[i] = - (takerTokenAmounts[i] * exchangeRate) / - (EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals); - } - } - } - - function sampleBuysFromCompound( - ICToken cToken, - IERC20TokenV06 takerToken, - IERC20TokenV06 makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - // Exchange rate is scaled by 1 * 10^(18 - 8 + Underlying Token Decimals - uint256 exchangeRate = cToken.exchangeRateStored(); - uint256 cTokenDecimals = uint256(cToken.decimals()); - - if (address(makerToken) == address(cToken)) { - // mint - for (uint256 i = 0; i < numSamples; i++) { - takerTokenAmounts[i] = - (makerTokenAmounts[i] * exchangeRate) / - (EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals); - } - } else if (address(takerToken) == address(cToken)) { - // redeem - for (uint256 i = 0; i < numSamples; i++) { - takerTokenAmounts[i] = - (makerTokenAmounts[i] * EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals) / - exchangeRate; - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/CurveSampler.sol b/contracts/zero-ex/contracts/test/samplers/CurveSampler.sol deleted file mode 100644 index d0ac1ec2da..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/CurveSampler.sol +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/ICurve.sol"; -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -contract CurveSampler is SamplerUtils, ApproximateBuys { - /// @dev Information for sampling from curve sources. - struct CurveInfo { - address poolAddress; - bytes4 sellQuoteFunctionSelector; - bytes4 buyQuoteFunctionSelector; - } - - /// @dev Base gas limit for Curve calls. Some Curves have multiple tokens - /// So a reasonable ceil is 150k per token. Biggest Curve has 4 tokens. - uint256 private constant CURVE_CALL_GAS = 2000e3; // Was 600k for Curve but SnowSwap is using 1500k+ - - /// @dev Sample sell quotes from Curve. - /// @param curveInfo Curve information specific to this token pair. - /// @param fromTokenIdx Index of the taker token (what to sell). - /// @param toTokenIdx Index of the maker token (what to buy). - /// @param takerTokenAmounts Taker token sell amount for each sample. - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromCurve( - CurveInfo memory curveInfo, - int128 fromTokenIdx, - int128 toTokenIdx, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - (bool didSucceed, bytes memory resultData) = curveInfo.poolAddress.staticcall.gas(CURVE_CALL_GAS)( - abi.encodeWithSelector( - curveInfo.sellQuoteFunctionSelector, - fromTokenIdx, - toTokenIdx, - takerTokenAmounts[i] - ) - ); - uint256 buyAmount = 0; - if (didSucceed) { - buyAmount = abi.decode(resultData, (uint256)); - } - makerTokenAmounts[i] = buyAmount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Sample buy quotes from Curve. - /// @param curveInfo Curve information specific to this token pair. - /// @param fromTokenIdx Index of the taker token (what to sell). - /// @param toTokenIdx Index of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromCurve( - CurveInfo memory curveInfo, - int128 fromTokenIdx, - int128 toTokenIdx, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - if (curveInfo.buyQuoteFunctionSelector == bytes4(0)) { - // Buys not supported on this curve, so approximate it. - return - _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(toTokenIdx, curveInfo), - takerTokenData: abi.encode(fromTokenIdx, curveInfo), - getSellQuoteCallback: _sampleSellForApproximateBuyFromCurve - }), - makerTokenAmounts - ); - } - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - (bool didSucceed, bytes memory resultData) = curveInfo.poolAddress.staticcall.gas(CURVE_CALL_GAS)( - abi.encodeWithSelector( - curveInfo.buyQuoteFunctionSelector, - fromTokenIdx, - toTokenIdx, - makerTokenAmounts[i] - ) - ); - uint256 sellAmount = 0; - if (didSucceed) { - sellAmount = abi.decode(resultData, (uint256)); - } - takerTokenAmounts[i] = sellAmount; - // Break early if there are 0 amounts - if (takerTokenAmounts[i] == 0) { - break; - } - } - } - - function _sampleSellForApproximateBuyFromCurve( - bytes memory takerTokenData, - bytes memory makerTokenData, - uint256 sellAmount - ) private view returns (uint256 buyAmount) { - (int128 takerTokenIdx, CurveInfo memory curveInfo) = abi.decode(takerTokenData, (int128, CurveInfo)); - int128 makerTokenIdx = abi.decode(makerTokenData, (int128)); - (bool success, bytes memory resultData) = address(this).staticcall( - abi.encodeWithSelector( - this.sampleSellsFromCurve.selector, - curveInfo, - takerTokenIdx, - makerTokenIdx, - _toSingleValueArray(sellAmount) - ) - ); - if (!success) { - return 0; - } - // solhint-disable-next-line indent - return abi.decode(resultData, (uint256[]))[0]; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/DODOSampler.sol b/contracts/zero-ex/contracts/test/samplers/DODOSampler.sol deleted file mode 100644 index 5761cb77d4..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/DODOSampler.sol +++ /dev/null @@ -1,184 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -interface IDODOZoo { - function getDODO(address baseToken, address quoteToken) external view returns (address); -} - -interface IDODOHelper { - function querySellQuoteToken(address dodo, uint256 amount) external view returns (uint256); -} - -interface IDODO { - function querySellBaseToken(uint256 amount) external view returns (uint256); - - function _TRADE_ALLOWED_() external view returns (bool); -} - -contract DODOSampler is SamplerUtils, ApproximateBuys { - /// @dev Gas limit for DODO calls. - uint256 private constant DODO_CALL_GAS = 300e3; // 300k - struct DODOSamplerOpts { - address registry; - address helper; - } - - /// @dev Sample sell quotes from DODO. - /// @param opts DODOSamplerOpts DODO Registry and helper addresses - /// @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( - DODOSamplerOpts memory opts, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (bool sellBase, address pool, uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - pool = IDODOZoo(opts.registry).getDODO(takerToken, makerToken); - address baseToken; - // If pool exists we have the correct order of Base/Quote - if (pool != address(0)) { - baseToken = takerToken; - sellBase = true; - } else { - pool = IDODOZoo(opts.registry).getDODO(makerToken, takerToken); - // No pool either direction - if (address(pool) == address(0)) { - return (sellBase, pool, makerTokenAmounts); - } - baseToken = makerToken; - sellBase = false; - } - - // DODO Pool has been disabled - if (!IDODO(pool)._TRADE_ALLOWED_()) { - return (sellBase, pool, makerTokenAmounts); - } - - for (uint256 i = 0; i < numSamples; i++) { - uint256 buyAmount = _sampleSellForApproximateBuyFromDODO( - abi.encode(takerToken, pool, baseToken, opts.helper), // taker token data - abi.encode(makerToken, pool, baseToken, opts.helper), // maker token data - takerTokenAmounts[i] - ); - makerTokenAmounts[i] = buyAmount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Sample buy quotes from DODO. - /// @param opts DODOSamplerOpts DODO Registry and helper addresses - /// @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( - DODOSamplerOpts memory opts, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - - // Pool is BASE/QUOTE - // Look up the pool from the taker/maker combination - pool = IDODOZoo(opts.registry).getDODO(takerToken, makerToken); - address baseToken; - // If pool exists we have the correct order of Base/Quote - if (pool != address(0)) { - baseToken = takerToken; - sellBase = true; - } else { - // Look up the pool from the maker/taker combination - pool = IDODOZoo(opts.registry).getDODO(makerToken, takerToken); - // No pool either direction - if (address(pool) == address(0)) { - return (sellBase, pool, takerTokenAmounts); - } - baseToken = makerToken; - sellBase = false; - } - - // DODO Pool has been disabled - if (!IDODO(pool)._TRADE_ALLOWED_()) { - return (sellBase, pool, takerTokenAmounts); - } - - takerTokenAmounts = _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(makerToken, pool, baseToken, opts.helper), - takerTokenData: abi.encode(takerToken, pool, baseToken, opts.helper), - getSellQuoteCallback: _sampleSellForApproximateBuyFromDODO - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromDODO( - bytes memory takerTokenData, - bytes memory /* makerTokenData */, - uint256 sellAmount - ) private view returns (uint256) { - (address takerToken, address pool, address baseToken, address helper) = abi.decode( - takerTokenData, - (address, address, address, address) - ); - - // 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 - 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 - try IDODOHelper(helper).querySellQuoteToken{gas: DODO_CALL_GAS}(pool, sellAmount) returns (uint256 amount) { - return amount; - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - return 0; - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/DODOV2Sampler.sol b/contracts/zero-ex/contracts/test/samplers/DODOV2Sampler.sol deleted file mode 100644 index bcd5c9457f..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/DODOV2Sampler.sol +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -interface IDODOV2Registry { - function getDODOPool(address baseToken, address quoteToken) external view returns (address[] memory machines); -} - -interface IDODOV2Pool { - function querySellBase( - address trader, - uint256 payBaseAmount - ) external view returns (uint256 receiveQuoteAmount, uint256 mtFee); - - function querySellQuote( - address trader, - uint256 payQuoteAmount - ) external view returns (uint256 receiveBaseAmount, uint256 mtFee); -} - -contract DODOV2Sampler is SamplerUtils, ApproximateBuys { - /// @dev Gas limit for DODO V2 calls. - uint256 private constant DODO_V2_CALL_GAS = 300e3; // 300k - - /// @dev Sample sell quotes from DODO V2. - /// @param registry Address of the registry to look up. - /// @param offset offset index for the pool in the registry. - /// @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 sampleSellsFromDODOV2( - address registry, - uint256 offset, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (bool sellBase, address pool, uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - (pool, sellBase) = _getNextDODOV2Pool(registry, offset, takerToken, makerToken); - if (pool == address(0)) { - return (sellBase, pool, makerTokenAmounts); - } - - for (uint256 i = 0; i < numSamples; i++) { - uint256 buyAmount = _sampleSellForApproximateBuyFromDODOV2( - abi.encode(takerToken, pool, sellBase), // taker token data - abi.encode(makerToken, pool, sellBase), // maker token data - takerTokenAmounts[i] - ); - makerTokenAmounts[i] = buyAmount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Sample buy quotes from DODO. - /// @param registry Address of the registry to look up. - /// @param offset offset index for the pool in the registry. - /// @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 sampleBuysFromDODOV2( - address registry, - uint256 offset, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - (pool, sellBase) = _getNextDODOV2Pool(registry, offset, takerToken, makerToken); - if (pool == address(0)) { - return (sellBase, pool, takerTokenAmounts); - } - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - - takerTokenAmounts = _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(makerToken, pool, !sellBase), - takerTokenData: abi.encode(takerToken, pool, sellBase), - getSellQuoteCallback: _sampleSellForApproximateBuyFromDODOV2 - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromDODOV2( - bytes memory takerTokenData, - bytes memory /* makerTokenData */, - uint256 sellAmount - ) private view returns (uint256) { - (address takerToken, address pool, bool sellBase) = abi.decode(takerTokenData, (address, address, bool)); - - // We will get called to sell both the taker token and also to sell the maker token - // since we use approximate buy for sell and buy functions - if (sellBase) { - try IDODOV2Pool(pool).querySellBase{gas: DODO_V2_CALL_GAS}(address(0), sellAmount) returns ( - uint256 amount, - uint256 - ) { - return amount; - } catch { - return 0; - } - } else { - try IDODOV2Pool(pool).querySellQuote{gas: DODO_V2_CALL_GAS}(address(0), sellAmount) returns ( - uint256 amount, - uint256 - ) { - return amount; - } catch { - return 0; - } - } - } - - function _getNextDODOV2Pool( - address registry, - uint256 offset, - address takerToken, - address makerToken - ) internal view returns (address machine, bool sellBase) { - // Query in base -> quote direction, if a pool is found then we are selling the base - address[] memory machines = IDODOV2Registry(registry).getDODOPool(takerToken, makerToken); - sellBase = true; - if (machines.length == 0) { - // Query in quote -> base direction, if a pool is found then we are selling the quote - machines = IDODOV2Registry(registry).getDODOPool(makerToken, takerToken); - sellBase = false; - } - - if (offset >= machines.length) { - return (address(0), false); - } - - machine = machines[offset]; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/ERC20BridgeSampler.sol b/contracts/zero-ex/contracts/test/samplers/ERC20BridgeSampler.sol deleted file mode 100644 index 1b857e9bf9..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/ERC20BridgeSampler.sol +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./BalancerSampler.sol"; -import "./BalancerV2Sampler.sol"; -import "./BalancerV2BatchSampler.sol"; -import "./BancorSampler.sol"; -import "./BancorV3Sampler.sol"; -import "./CompoundSampler.sol"; -import "./CurveSampler.sol"; -import "./DODOSampler.sol"; -import "./DODOV2Sampler.sol"; -import "./GMXSampler.sol"; -import "./KyberDmmSampler.sol"; -import "./LidoSampler.sol"; -import "./MakerPSMSampler.sol"; -import "./MStableSampler.sol"; -import "./MooniswapSampler.sol"; -import "./NativeOrderSampler.sol"; -import "./PlatypusSampler.sol"; -import "./ShellSampler.sol"; -import "./SynthetixSampler.sol"; -import "./TwoHopSampler.sol"; -import "./UniswapSampler.sol"; -import "./UniswapV2Sampler.sol"; -import "./UniswapV3Sampler.sol"; -import "./VelodromeSampler.sol"; -import "./WooPPSampler.sol"; -import "./UtilitySampler.sol"; - -contract ERC20BridgeSampler is - BalancerSampler, - BalancerV2Sampler, - BalancerV2BatchSampler, - BancorSampler, - BancorV3Sampler, - CompoundSampler, - CurveSampler, - DODOSampler, - DODOV2Sampler, - GMXSampler, - KyberDmmSampler, - LidoSampler, - MakerPSMSampler, - MStableSampler, - MooniswapSampler, - NativeOrderSampler, - PlatypusSampler, - ShellSampler, - SynthetixSampler, - TwoHopSampler, - UniswapSampler, - UniswapV2Sampler, - UniswapV3Sampler, - VelodromeSampler, - WooPPSampler, - UtilitySampler -{ - struct CallResults { - bytes data; - bool success; - } - - /// @dev Call multiple public functions on this contract in a single transaction. - /// @param callDatas ABI-encoded call data for each function call. - /// @return callResults ABI-encoded results data for each call. - function batchCall(bytes[] calldata callDatas) external returns (CallResults[] memory callResults) { - callResults = new CallResults[](callDatas.length); - for (uint256 i = 0; i != callDatas.length; ++i) { - callResults[i].success = true; - if (callDatas[i].length == 0) { - continue; - } - (callResults[i].success, callResults[i].data) = address(this).call(callDatas[i]); - } - } - - receive() external payable {} -} diff --git a/contracts/zero-ex/contracts/test/samplers/FakeTaker.sol b/contracts/zero-ex/contracts/test/samplers/FakeTaker.sol deleted file mode 100644 index a6a6c65c0d..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/FakeTaker.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -contract FakeTaker { - struct Result { - bool success; - bytes resultData; - uint256 gasUsed; - } - - receive() external payable {} - - function execute(address payable to, bytes calldata data) public payable returns (Result memory result) { - uint256 gasBefore = gasleft(); - (result.success, result.resultData) = to.call{value: msg.value}(data); - result.gasUsed = gasBefore - gasleft(); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/GMXSampler.sol b/contracts/zero-ex/contracts/test/samplers/GMXSampler.sol deleted file mode 100644 index 6f27318e31..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/GMXSampler.sol +++ /dev/null @@ -1,85 +0,0 @@ -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IGMX.sol"; -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -contract GMXSampler is SamplerUtils, ApproximateBuys { - struct GMXInfo { - address reader; - address vault; - address[] path; - } - - function sampleSellsFromGMX( - address reader, - address vault, - address[] memory path, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - try IGMX(reader).getAmountOut(IVault(vault), path[0], path[1], takerTokenAmounts[i]) returns ( - uint256 amountAfterFees, - uint256 feeAmount - ) { - makerTokenAmounts[i] = amountAfterFees; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - function sampleBuysFromGMX( - address reader, - address vault, - address[] memory path, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - address[] memory invertBuyPath = new address[](2); - invertBuyPath[0] = path[1]; - invertBuyPath[1] = path[0]; - return - _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(reader, vault, invertBuyPath), - takerTokenData: abi.encode(reader, vault, path), - getSellQuoteCallback: _sampleSellForApproximateBuyFromGMX - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromGMX( - bytes memory takerTokenData, - bytes memory makerTokenData, - uint256 sellAmount - ) private view returns (uint256 buyAmount) { - (address _reader, address _vault, address[] memory _path) = abi.decode( - takerTokenData, - (address, address, address[]) - ); - - (bool success, bytes memory resultData) = address(this).staticcall( - abi.encodeWithSelector( - this.sampleSellsFromGMX.selector, - _reader, - _vault, - _path, - _toSingleValueArray(sellAmount) - ) - ); - if (!success) { - return 0; - } - // solhint-disable-next-line indent - return abi.decode(resultData, (uint256[]))[0]; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/KyberDmmSampler.sol b/contracts/zero-ex/contracts/test/samplers/KyberDmmSampler.sol deleted file mode 100644 index 42b3111e19..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/KyberDmmSampler.sol +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -interface IKyberDmmPool { - function totalSupply() external view returns (uint256); -} - -interface IKyberDmmFactory { - function getPools(address token0, address token1) external view returns (address[] memory _tokenPools); -} - -interface IKyberDmmRouter { - function factory() external view returns (address); - - function getAmountsOut( - uint256 amountIn, - address[] calldata pools, - address[] calldata path - ) external view returns (uint256[] memory amounts); - - function getAmountsIn( - uint256 amountOut, - address[] calldata pools, - address[] calldata path - ) external view returns (uint256[] memory amounts); -} - -contract KyberDmmSampler { - /// @dev Gas limit for KyberDmm calls. - uint256 private constant KYBER_DMM_CALL_GAS = 150e3; // 150k - - /// @dev Sample sell quotes from KyberDmm. - /// @param router Router to look up tokens and amounts - /// @param path Token route. Should be takerToken -> makerToken - /// @param takerTokenAmounts Taker token sell amount for each sample. - /// @return pools The pool addresses involved in the multi path trade - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromKyberDmm( - address router, - address[] memory path, - uint256[] memory takerTokenAmounts - ) public view returns (address[] memory pools, uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - pools = _getKyberDmmPools(router, path); - if (pools.length == 0) { - return (pools, makerTokenAmounts); - } - for (uint256 i = 0; i < numSamples; i++) { - try - IKyberDmmRouter(router).getAmountsOut{gas: KYBER_DMM_CALL_GAS}(takerTokenAmounts[i], pools, path) - returns (uint256[] memory amounts) { - makerTokenAmounts[i] = amounts[path.length - 1]; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Sample buy quotes from KyberDmm. - /// @param router Router to look up tokens and amounts - /// @param path Token route. Should be takerToken -> makerToken. - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return pools The pool addresses involved in the multi path trade - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromKyberDmm( - address router, - address[] memory path, - uint256[] memory makerTokenAmounts - ) public view returns (address[] memory pools, uint256[] memory takerTokenAmounts) { - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - pools = _getKyberDmmPools(router, path); - if (pools.length == 0) { - return (pools, takerTokenAmounts); - } - for (uint256 i = 0; i < numSamples; i++) { - try - IKyberDmmRouter(router).getAmountsIn{gas: KYBER_DMM_CALL_GAS}(makerTokenAmounts[i], pools, path) - returns (uint256[] memory amounts) { - takerTokenAmounts[i] = amounts[0]; - // Break early if there are 0 amounts - if (takerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - function _getKyberDmmPools(address router, address[] memory path) private view returns (address[] memory pools) { - IKyberDmmFactory factory = IKyberDmmFactory(IKyberDmmRouter(router).factory()); - pools = new address[](path.length - 1); - for (uint256 i = 0; i < pools.length; i++) { - // find the best pool - address[] memory allPools; - try factory.getPools{gas: KYBER_DMM_CALL_GAS}(path[i], path[i + 1]) returns (address[] memory allPools) { - if (allPools.length == 0) { - return new address[](0); - } - - uint256 maxSupply = 0; - for (uint256 j = 0; j < allPools.length; j++) { - uint256 totalSupply = IKyberDmmPool(allPools[j]).totalSupply(); - if (totalSupply > maxSupply) { - maxSupply = totalSupply; - pools[i] = allPools[j]; - } - } - } catch (bytes memory) { - return new address[](0); - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/LidoSampler.sol b/contracts/zero-ex/contracts/test/samplers/LidoSampler.sol deleted file mode 100644 index 33a77b7765..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/LidoSampler.sol +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./SamplerUtils.sol"; - -interface IWstETH { - function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256); - - function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); -} - -contract LidoSampler is SamplerUtils { - struct LidoInfo { - address stEthToken; - address wethToken; - address wstEthToken; - } - - /// @dev Sample sell quotes from Lido - /// @param lidoInfo Info regarding a specific Lido deployment - /// @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 makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromLido( - LidoInfo memory lidoInfo, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory) { - _assertValidPair(makerToken, takerToken); - - if (takerToken == lidoInfo.wethToken && makerToken == address(lidoInfo.stEthToken)) { - // Minting stETH is always 1:1 therefore we can just return the same amounts back. - return takerTokenAmounts; - } - - return _sampleSellsForWrapped(lidoInfo, takerToken, makerToken, takerTokenAmounts); - } - - /// @dev Sample buy quotes from Lido. - /// @param lidoInfo Info regarding a specific Lido deployment - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromLido( - LidoInfo memory lidoInfo, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory) { - if (takerToken == lidoInfo.wethToken && makerToken == address(lidoInfo.stEthToken)) { - // Minting stETH is always 1:1 therefore we can just return the same amounts back. - return makerTokenAmounts; - } - - // Swap out `makerToken` and `takerToken` and re-use `_sampleSellsForWrapped`. - return _sampleSellsForWrapped(lidoInfo, makerToken, takerToken, makerTokenAmounts); - } - - function _sampleSellsForWrapped( - LidoInfo memory lidoInfo, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) private view returns (uint256[] memory) { - IWstETH wstETH = IWstETH(lidoInfo.wstEthToken); - uint256 numSamples = takerTokenAmounts.length; - uint256[] memory makerTokenAmounts = new uint256[](numSamples); - - if (takerToken == lidoInfo.stEthToken && makerToken == lidoInfo.wstEthToken) { - for (uint256 i = 0; i < numSamples; i++) { - makerTokenAmounts[i] = wstETH.getWstETHByStETH(takerTokenAmounts[i]); - } - return makerTokenAmounts; - } - - if (takerToken == lidoInfo.wstEthToken && makerToken == lidoInfo.stEthToken) { - for (uint256 i = 0; i < numSamples; i++) { - makerTokenAmounts[i] = wstETH.getStETHByWstETH(takerTokenAmounts[i]); - } - return makerTokenAmounts; - } - - // Returns 0 values. - return makerTokenAmounts; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/MStableSampler.sol b/contracts/zero-ex/contracts/test/samplers/MStableSampler.sol deleted file mode 100644 index 45662c43cb..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/MStableSampler.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IMStable.sol"; -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -contract MStableSampler is SamplerUtils, ApproximateBuys { - /// @dev Default gas limit for mStable calls. - uint256 private constant DEFAULT_CALL_GAS = 800e3; // 800k - - /// @dev Sample sell quotes from the mStable contract - /// @param router Address of the mStable contract - /// @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 makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromMStable( - address router, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - // Initialize array of maker token amounts. - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - for (uint256 i = 0; i < numSamples; i++) { - try - IMStable(router).getSwapOutput{gas: DEFAULT_CALL_GAS}(takerToken, makerToken, takerTokenAmounts[i]) - returns (uint256 amount) { - makerTokenAmounts[i] = amount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Sample buy quotes from MStable contract - /// @param router Address of the mStable contract - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromMStable( - address router, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - return - _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(makerToken, router), - takerTokenData: abi.encode(takerToken, router), - getSellQuoteCallback: _sampleSellForApproximateBuyFromMStable - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromMStable( - bytes memory takerTokenData, - bytes memory makerTokenData, - uint256 sellAmount - ) private view returns (uint256 buyAmount) { - (address takerToken, address router) = abi.decode(takerTokenData, (address, address)); - address makerToken = abi.decode(makerTokenData, (address)); - try this.sampleSellsFromMStable(router, takerToken, makerToken, _toSingleValueArray(sellAmount)) returns ( - uint256[] memory amounts - ) { - return amounts[0]; - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - return 0; - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/MakerPSMSampler.sol b/contracts/zero-ex/contracts/test/samplers/MakerPSMSampler.sol deleted file mode 100644 index eb06db6bae..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/MakerPSMSampler.sol +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "./SamplerUtils.sol"; -import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol"; - -interface IPSM { - // @dev Get the fee for selling USDC to DAI in PSM - // @return tin toll in [wad] - function tin() external view returns (uint256); - - // @dev Get the fee for selling DAI to USDC in PSM - // @return tout toll out [wad] - function tout() external view returns (uint256); - - // @dev Get the address of the PSM state Vat - // @return address of the Vat - function vat() external view returns (address); - - // @dev Get the address of the underlying vault powering PSM - // @return address of gemJoin contract - function gemJoin() external view returns (address); - - // @dev Get the address of DAI - // @return address of DAI contract - function dai() external view returns (address); - - // @dev Sell USDC for DAI - // @param usr The address of the account trading USDC for DAI. - // @param gemAmt The amount of USDC to sell in USDC base units - function sellGem(address usr, uint256 gemAmt) external; - - // @dev Buy USDC for DAI - // @param usr The address of the account trading DAI for USDC - // @param gemAmt The amount of USDC to buy in USDC base units - function buyGem(address usr, uint256 gemAmt) external; -} - -interface IVAT { - // @dev Get a collateral type by identifier - // @param ilkIdentifier bytes32 identifier. Example: ethers.utils.formatBytes32String("PSM-USDC-A") - // @return ilk - // @return ilk.Art Total Normalised Debt in wad - // @return ilk.rate Accumulated Rates in ray - // @return ilk.spot Price with Safety Margin in ray - // @return ilk.line Debt Ceiling in rad - // @return ilk.dust Urn Debt Floor in rad - function ilks( - bytes32 ilkIdentifier - ) external view returns (uint256 Art, uint256 rate, uint256 spot, uint256 line, uint256 dust); -} - -contract MakerPSMSampler is SamplerUtils { - using LibSafeMathV06 for uint256; - - /// @dev Information about which PSM module to use - struct MakerPsmInfo { - address psmAddress; - bytes32 ilkIdentifier; - address gemTokenAddress; - } - - /// @dev Gas limit for MakerPsm calls. - uint256 private constant MAKER_PSM_CALL_GAS = 300e3; // 300k - - // Maker units - // wad: fixed point decimal with 18 decimals (for basic quantities, e.g. balances) - uint256 private constant WAD = 10 ** 18; - // ray: fixed point decimal with 27 decimals (for precise quantites, e.g. ratios) - uint256 private constant RAY = 10 ** 27; - // rad: fixed point decimal with 45 decimals (result of integer multiplication with a wad and a ray) - uint256 private constant RAD = 10 ** 45; - - // See https://github.com/makerdao/dss/blob/master/DEVELOPING.m - - /// @dev Sample sell quotes from Maker PSM - function sampleSellsFromMakerPsm( - MakerPsmInfo memory psmInfo, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - IPSM psm = IPSM(psmInfo.psmAddress); - IVAT vat = IVAT(psm.vat()); - - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - if (makerToken != psm.dai() && takerToken != psm.dai()) { - return makerTokenAmounts; - } - - for (uint256 i = 0; i < numSamples; i++) { - uint256 buyAmount = _samplePSMSell(psmInfo, makerToken, takerToken, takerTokenAmounts[i], psm, vat); - - if (buyAmount == 0) { - break; - } - makerTokenAmounts[i] = buyAmount; - } - } - - function sampleBuysFromMakerPsm( - MakerPsmInfo memory psmInfo, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - IPSM psm = IPSM(psmInfo.psmAddress); - IVAT vat = IVAT(psm.vat()); - - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - if (makerToken != psm.dai() && takerToken != psm.dai()) { - return takerTokenAmounts; - } - - for (uint256 i = 0; i < numSamples; i++) { - uint256 sellAmount = _samplePSMBuy(psmInfo, makerToken, takerToken, makerTokenAmounts[i], psm, vat); - - if (sellAmount == 0) { - break; - } - - takerTokenAmounts[i] = sellAmount; - } - } - - function _samplePSMSell( - MakerPsmInfo memory psmInfo, - address makerToken, - address takerToken, - uint256 takerTokenAmount, - IPSM psm, - IVAT vat - ) private view returns (uint256) { - (uint256 totalDebtInWad, , , uint256 debtCeilingInRad, uint256 debtFloorInRad) = vat.ilks( - psmInfo.ilkIdentifier - ); - uint256 gemTokenBaseUnit = uint256(1e6); - - if (takerToken == psmInfo.gemTokenAddress) { - // Simulate sellGem - // Selling USDC to the PSM, increasing the total debt - // Convert USDC 6 decimals to 18 decimals [wad] - uint256 takerTokenAmountInWad = takerTokenAmount.safeMul(1e12); - - uint256 newTotalDebtInRad = totalDebtInWad.safeAdd(takerTokenAmountInWad).safeMul(RAY); - - // PSM is too full to fit - if (newTotalDebtInRad >= debtCeilingInRad) { - return 0; - } - - uint256 feeInWad = takerTokenAmountInWad.safeMul(psm.tin()).safeDiv(WAD); - uint256 makerTokenAmountInWad = takerTokenAmountInWad.safeSub(feeInWad); - - return makerTokenAmountInWad; - } else if (makerToken == psmInfo.gemTokenAddress) { - // Simulate buyGem - // Buying USDC from the PSM, decreasing the total debt - // Selling DAI for USDC, already in 18 decimals [wad] - uint256 takerTokenAmountInWad = takerTokenAmount; - if (takerTokenAmountInWad > totalDebtInWad) { - return 0; - } - uint256 newTotalDebtInRad = totalDebtInWad.safeSub(takerTokenAmountInWad).safeMul(RAY); - - // PSM is empty, not enough USDC to buy from it - if (newTotalDebtInRad <= debtFloorInRad) { - return 0; - } - - uint256 feeDivisorInWad = WAD.safeAdd(psm.tout()); // eg. 1.001 * 10 ** 18 with 0.1% tout; - uint256 makerTokenAmountInGemTokenBaseUnits = takerTokenAmountInWad.safeMul(gemTokenBaseUnit).safeDiv( - feeDivisorInWad - ); - - return makerTokenAmountInGemTokenBaseUnits; - } - - return 0; - } - - function _samplePSMBuy( - MakerPsmInfo memory psmInfo, - address makerToken, - address takerToken, - uint256 makerTokenAmount, - IPSM psm, - IVAT vat - ) private view returns (uint256) { - (uint256 totalDebtInWad, , , uint256 debtCeilingInRad, uint256 debtFloorInRad) = vat.ilks( - psmInfo.ilkIdentifier - ); - - if (takerToken == psmInfo.gemTokenAddress) { - // Simulate sellGem - // Selling USDC to the PSM, increasing the total debt - uint256 makerTokenAmountInWad = makerTokenAmount; - uint256 feeDivisorInWad = WAD.safeSub(psm.tin()); // eg. 0.999 * 10 ** 18 with 0.1% tin; - uint256 takerTokenAmountInWad = makerTokenAmountInWad.safeMul(WAD).safeDiv(feeDivisorInWad); - uint256 newTotalDebtInRad = totalDebtInWad.safeAdd(takerTokenAmountInWad).safeMul(RAY); - - // PSM is too full to fit - if (newTotalDebtInRad >= debtCeilingInRad) { - return 0; - } - - uint256 takerTokenAmountInGemInGemBaseUnits = (takerTokenAmountInWad.safeDiv(1e12)).safeAdd(1); // Add 1 to deal with cut off decimals converting to lower decimals - - return takerTokenAmountInGemInGemBaseUnits; - } else if (makerToken == psmInfo.gemTokenAddress) { - // Simulate buyGem - // Buying USDC from the PSM, decreasing the total debt - uint256 makerTokenAmountInWad = makerTokenAmount.safeMul(1e12); - uint256 feeMultiplierInWad = WAD.safeAdd(psm.tout()); // eg. 1.001 * 10 ** 18 with 0.1% tout; - uint256 takerTokenAmountInWad = makerTokenAmountInWad.safeMul(feeMultiplierInWad).safeDiv(WAD); - if (takerTokenAmountInWad > totalDebtInWad) { - return 0; - } - uint256 newTotalDebtInRad = totalDebtInWad.safeSub(takerTokenAmountInWad).safeMul(RAY); - - // PSM is empty, not enough USDC to buy - if (newTotalDebtInRad <= debtFloorInRad) { - return 0; - } - - return takerTokenAmountInWad; - } - - return 0; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/MooniswapSampler.sol b/contracts/zero-ex/contracts/test/samplers/MooniswapSampler.sol deleted file mode 100644 index 21e06b8c5d..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/MooniswapSampler.sol +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IMooniswap.sol"; -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -contract MooniswapSampler is SamplerUtils, ApproximateBuys { - /// @dev Gas limit for Mooniswap calls. - uint256 private constant MOONISWAP_CALL_GAS = 150e3; // 150k - - /// @dev Sample sell quotes from Mooniswap. - /// @param registry Address of the Mooniswap Registry. - /// @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( - address registry, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (IMooniswap pool, uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - for (uint256 i = 0; i < numSamples; i++) { - uint256 buyAmount = sampleSingleSellFromMooniswapPool( - registry, - takerToken, - makerToken, - takerTokenAmounts[i] - ); - makerTokenAmounts[i] = buyAmount; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } - - pool = IMooniswap(IMooniswapRegistry(registry).pools(takerToken, makerToken)); - } - - function sampleSingleSellFromMooniswapPool( - address registry, - address mooniswapTakerToken, - address mooniswapMakerToken, - uint256 takerTokenAmount - ) public view returns (uint256) { - // Find the pool for the pair. - IMooniswap pool = IMooniswap(IMooniswapRegistry(registry).pools(mooniswapTakerToken, mooniswapMakerToken)); - // If there is no pool then return early - if (address(pool) == address(0)) { - return 0; - } - uint256 poolBalance = mooniswapTakerToken == address(0) - ? address(pool).balance - : 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 0; - } - 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; - } - } - - /// @dev Sample buy quotes from Mooniswap. - /// @param registry Address of the Mooniswap Registry. - /// @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( - address registry, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (IMooniswap pool, uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - - takerTokenAmounts = _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(registry, makerToken), - takerTokenData: abi.encode(registry, takerToken), - getSellQuoteCallback: _sampleSellForApproximateBuyFromMooniswap - }), - makerTokenAmounts - ); - - pool = IMooniswap(IMooniswapRegistry(registry).pools(takerToken, makerToken)); - } - - function _sampleSellForApproximateBuyFromMooniswap( - bytes memory takerTokenData, - bytes memory makerTokenData, - uint256 sellAmount - ) private view returns (uint256 buyAmount) { - (address registry, address mooniswapTakerToken) = abi.decode(takerTokenData, (address, address)); - (address _registry, address mooniswapMakerToken) = abi.decode(makerTokenData, (address, address)); - return sampleSingleSellFromMooniswapPool(registry, mooniswapTakerToken, mooniswapMakerToken, sellAmount); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/NativeOrderSampler.sol b/contracts/zero-ex/contracts/test/samplers/NativeOrderSampler.sol deleted file mode 100644 index 50885c7f08..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/NativeOrderSampler.sol +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -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 { - enum OrderStatus { - INVALID, - FILLABLE, - FILLED, - CANCELLED, - EXPIRED - } - - /// @dev A standard OTC or OO limit order. - struct LimitOrder { - IERC20TokenV06 makerToken; - IERC20TokenV06 takerToken; - uint128 makerAmount; - uint128 takerAmount; - uint128 takerTokenFeeAmount; - address maker; - address taker; - address sender; - address feeRecipient; - bytes32 pool; - uint64 expiry; - uint256 salt; - } - - /// @dev An RFQ limit order. - struct RfqOrder { - IERC20TokenV06 makerToken; - IERC20TokenV06 takerToken; - uint128 makerAmount; - uint128 takerAmount; - address maker; - address taker; - address txOrigin; - bytes32 pool; - uint64 expiry; - uint256 salt; - } - - /// @dev Info on a limit or RFQ order. - struct OrderInfo { - bytes32 orderHash; - OrderStatus status; - uint128 takerTokenFilledAmount; - } - - /// @dev Allowed signature types. - enum SignatureType { - ILLEGAL, - INVALID, - EIP712, - ETHSIGN - } - - /// @dev Encoded EC signature. - struct Signature { - // How to validate the signature. - SignatureType signatureType; - // EC Signature data. - uint8 v; - // EC Signature data. - bytes32 r; - // EC Signature data. - bytes32 s; - } - - /// @dev Get the order info for a limit order. - /// @param order The limit order. - /// @return orderInfo Info about the order. - function getLimitOrderInfo(LimitOrder memory order) external view returns (OrderInfo memory orderInfo); - - /// @dev Get order info, fillable amount, and signature validity for a limit order. - /// Fillable amount is determined using balances and allowances of the maker. - /// @param order The limit order. - /// @param signature The order signature. - /// @return orderInfo Info about the order. - /// @return actualFillableTakerTokenAmount How much of the order is fillable - /// based on maker funds, in taker tokens. - /// @return isSignatureValid Whether the signature is valid. - function getLimitOrderRelevantState( - LimitOrder memory order, - Signature calldata signature - ) external view returns (OrderInfo memory orderInfo, uint128 actualFillableTakerTokenAmount, bool isSignatureValid); -} - -contract NativeOrderSampler { - using LibSafeMathV06 for uint256; - using LibBytesV06 for bytes; - - /// @dev Gas limit for calls to `getOrderFillableTakerAmount()`. - uint256 internal constant DEFAULT_CALL_GAS = 200e3; // 200k - - /// @dev Queries the fillable taker asset amounts of native orders. - /// Effectively ignores orders that have empty signatures or - /// maker/taker asset amounts (returning 0). - /// @param orders Native limit orders to query. - /// @param orderSignatures Signatures for each respective order in `orders`. - /// @param exchange The V4 exchange. - /// @return orderFillableTakerAssetAmounts How much taker asset can be filled - /// by each order in `orders`. - function getLimitOrderFillableTakerAssetAmounts( - IExchange.LimitOrder[] memory orders, - IExchange.Signature[] memory orderSignatures, - IExchange exchange - ) public view returns (uint256[] memory orderFillableTakerAssetAmounts) { - orderFillableTakerAssetAmounts = new uint256[](orders.length); - for (uint256 i = 0; i != orders.length; i++) { - try - this.getLimitOrderFillableTakerAmount{gas: DEFAULT_CALL_GAS}(orders[i], orderSignatures[i], exchange) - returns (uint256 amount) { - orderFillableTakerAssetAmounts[i] = amount; - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - orderFillableTakerAssetAmounts[i] = 0; - } - } - } - - /// @dev Queries the fillable taker asset amounts of native orders. - /// Effectively ignores orders that have empty signatures or - /// @param orders Native orders to query. - /// @param orderSignatures Signatures for each respective order in `orders`. - /// @param exchange The V4 exchange. - /// @return orderFillableMakerAssetAmounts How much maker asset can be filled - /// by each order in `orders`. - function getLimitOrderFillableMakerAssetAmounts( - IExchange.LimitOrder[] memory orders, - IExchange.Signature[] memory orderSignatures, - IExchange exchange - ) public view returns (uint256[] memory orderFillableMakerAssetAmounts) { - orderFillableMakerAssetAmounts = getLimitOrderFillableTakerAssetAmounts(orders, orderSignatures, exchange); - // `orderFillableMakerAssetAmounts` now holds taker asset amounts, so - // convert them to maker asset amounts. - for (uint256 i = 0; i < orders.length; ++i) { - if (orderFillableMakerAssetAmounts[i] != 0) { - orderFillableMakerAssetAmounts[i] = LibMathV06.getPartialAmountCeil( - orderFillableMakerAssetAmounts[i], - orders[i].takerAmount, - orders[i].makerAmount - ); - } - } - } - - /// @dev Get the fillable taker amount of an order, taking into account - /// order state, maker fees, and maker balances. - function getLimitOrderFillableTakerAmount( - IExchange.LimitOrder memory order, - IExchange.Signature memory signature, - IExchange exchange - ) public view virtual returns (uint256 fillableTakerAmount) { - if ( - signature.signatureType == IExchange.SignatureType.ILLEGAL || - signature.signatureType == IExchange.SignatureType.INVALID || - order.makerAmount == 0 || - order.takerAmount == 0 - ) { - return 0; - } - - (IExchange.OrderInfo memory orderInfo, uint128 remainingFillableTakerAmount, bool isSignatureValid) = exchange - .getLimitOrderRelevantState(order, signature); - - if ( - orderInfo.status != IExchange.OrderStatus.FILLABLE || - !isSignatureValid || - order.makerToken == IERC20TokenV06(0) - ) { - return 0; - } - - fillableTakerAmount = uint256(remainingFillableTakerAmount); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/PlatypusSampler.sol b/contracts/zero-ex/contracts/test/samplers/PlatypusSampler.sol deleted file mode 100644 index 60cdff1622..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/PlatypusSampler.sol +++ /dev/null @@ -1,68 +0,0 @@ -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IPlatypus.sol"; -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -contract PlatypusSampler is SamplerUtils, ApproximateBuys { - function sampleSellsFromPlatypus( - address pool, - address[] memory path, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - try IPlatypus(pool).quotePotentialSwap(path[0], path[1], takerTokenAmounts[i]) returns ( - uint256 amountAfterFees, - uint256 feeAmount - ) { - makerTokenAmounts[i] = amountAfterFees; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory result) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - function sampleBuysFromPlatypus( - address pool, - address[] memory path, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - address[] memory invertBuyPath = new address[](2); - invertBuyPath[0] = path[1]; - invertBuyPath[1] = path[0]; - return - _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(pool, invertBuyPath), - takerTokenData: abi.encode(pool, path), - getSellQuoteCallback: _sampleSellForApproximateBuyFromPlatypus - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromPlatypus( - bytes memory makerTokenData, - bytes memory takerTokenData, - uint256 sellAmount - ) private view returns (uint256 buyAmount) { - (address _pool, address[] memory _path) = abi.decode(makerTokenData, (address, address[])); - - (bool success, bytes memory resultData) = address(this).staticcall( - abi.encodeWithSelector(this.sampleSellsFromPlatypus.selector, _pool, _path, _toSingleValueArray(sellAmount)) - ); - if (!success) { - return 0; - } - // solhint-disable-next-line indent - return abi.decode(resultData, (uint256[]))[0]; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/SamplerUtils.sol b/contracts/zero-ex/contracts/test/samplers/SamplerUtils.sol deleted file mode 100644 index d4873564ff..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/SamplerUtils.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; - -contract SamplerUtils { - /// @dev Overridable way to get token decimals. - /// @param tokenAddress Address of the token. - /// @return decimals The decimal places for the token. - function _getTokenDecimals(address tokenAddress) internal view virtual returns (uint8 decimals) { - return LibERC20TokenV06.compatDecimals(IERC20TokenV06(tokenAddress)); - } - - function _toSingleValueArray(uint256 v) internal pure returns (uint256[] memory arr) { - arr = new uint256[](1); - arr[0] = v; - } - - /// @dev Assert that the tokens in a trade pair are valid. - /// @param makerToken Address of the maker token. - /// @param takerToken Address of the taker token. - function _assertValidPair(address makerToken, address takerToken) internal pure { - require(makerToken != takerToken, "ERC20BridgeSampler/INVALID_TOKEN_PAIR"); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/ShellSampler.sol b/contracts/zero-ex/contracts/test/samplers/ShellSampler.sol deleted file mode 100644 index ebf6b337b4..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/ShellSampler.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./ApproximateBuys.sol"; -import "./interfaces/IShell.sol"; -import "./SamplerUtils.sol"; - -contract ShellSampler is SamplerUtils, ApproximateBuys { - struct ShellInfo { - address poolAddress; - } - - /// @dev Default gas limit for Shell calls. - uint256 private constant DEFAULT_CALL_GAS = 300e3; // 300k - - /// @dev Sample sell quotes from the Shell pool contract - /// @param pool Address of the Shell pool contract - /// @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 makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromShell( - address pool, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - // Initialize array of maker token amounts. - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - for (uint256 i = 0; i < numSamples; i++) { - try - IShell(pool).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; - } - } - } - - /// @dev Sample buy quotes from Shell pool contract - /// @param pool Address of the Shell pool contract - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromShell( - address pool, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - return - _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - makerTokenData: abi.encode(makerToken, pool), - takerTokenData: abi.encode(takerToken, pool), - getSellQuoteCallback: _sampleSellForApproximateBuyFromShell - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromShell( - bytes memory takerTokenData, - bytes memory makerTokenData, - uint256 sellAmount - ) private view returns (uint256 buyAmount) { - (address takerToken, address pool) = abi.decode(takerTokenData, (address, address)); - address makerToken = abi.decode(makerTokenData, (address)); - - try this.sampleSellsFromShell(pool, takerToken, makerToken, _toSingleValueArray(sellAmount)) returns ( - uint256[] memory amounts - ) { - return amounts[0]; - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - return 0; - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/SynthetixSampler.sol b/contracts/zero-ex/contracts/test/samplers/SynthetixSampler.sol deleted file mode 100644 index f1bf0fac84..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/SynthetixSampler.sol +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2022 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; -pragma experimental ABIEncoderV2; - -interface IReadProxyAddressResolver { - function target() external view returns (address); -} - -interface IAddressResolver { - function getAddress(bytes32 name) external view returns (address); -} - -interface IExchanger { - // Ethereum Mainnet - function getAmountsForAtomicExchange( - uint256 sourceAmount, - bytes32 sourceCurrencyKey, - bytes32 destinationCurrencyKey - ) external view returns (uint256 amountReceived, uint256 fee, uint256 exchangeFeeRate); - - // Optimism - function getAmountsForExchange( - uint256 sourceAmount, - bytes32 sourceCurrencyKey, - bytes32 destinationCurrencyKey - ) external view returns (uint256 amountReceived, uint256 fee, uint256 exchangeFeeRate); -} - -contract SynthetixSampler { - /// @dev Sample sell quotes from Synthetix Atomic Swap. - /// @param takerTokenSymbol Symbol (currency key) of the taker token (what to sell). - /// @param makerTokenSymbol Symbol (currency key) of the maker token (what to buy). - /// @param takerTokenAmounts Taker token sell amount for each sample (sorted in ascending order). - /// @return synthetix Synthetix address. - /// @return makerTokenAmounts Maker amounts bought at each taker token amount. - function sampleSellsFromSynthetix( - IReadProxyAddressResolver readProxy, - bytes32 takerTokenSymbol, - bytes32 makerTokenSymbol, - uint256[] memory takerTokenAmounts - ) public view returns (address synthetix, uint256[] memory makerTokenAmounts) { - synthetix = getSynthetixAddress(readProxy); - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - if (numSamples == 0) { - return (synthetix, makerTokenAmounts); - } - - makerTokenAmounts[0] = exchange(readProxy, takerTokenAmounts[0], takerTokenSymbol, makerTokenSymbol); - - // Synthetix atomic swap has a fixed rate. Calculate the rest based on the first value (and save gas). - for (uint256 i = 1; i < numSamples; i++) { - makerTokenAmounts[i] = (makerTokenAmounts[0] * takerTokenAmounts[i]) / takerTokenAmounts[0]; - } - } - - /// @dev Sample buy quotes from Synthetix Atomic Swap. - /// @param takerTokenSymbol Symbol (currency key) of the taker token (what to sell). - /// @param makerTokenSymbol Symbol (currency key) of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample (sorted in ascending order). - /// @return synthetix Synthetix address. - /// @return takerTokenAmounts Taker amounts sold at each maker token amount. - function sampleBuysFromSynthetix( - IReadProxyAddressResolver readProxy, - bytes32 takerTokenSymbol, - bytes32 makerTokenSymbol, - uint256[] memory makerTokenAmounts - ) public view returns (address synthetix, uint256[] memory takerTokenAmounts) { - synthetix = getSynthetixAddress(readProxy); - // Since Synthetix atomic have a fixed rate, we can pick any reasonablely size takerTokenAmount (fixed to 1 ether here) and calculate the rest. - uint256 amountReceivedForEther = exchange(readProxy, 1 ether, takerTokenSymbol, makerTokenSymbol); - - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - - for (uint256 i = 0; i < numSamples; i++) { - takerTokenAmounts[i] = (1 ether * makerTokenAmounts[i]) / amountReceivedForEther; - } - } - - function exchange( - IReadProxyAddressResolver readProxy, - uint256 sourceAmount, - bytes32 sourceCurrencyKey, - bytes32 destinationCurrencyKey - ) private view returns (uint256 amountReceived) { - IExchanger exchanger = getExchanger(readProxy); - uint256 chainId; - assembly { - chainId := chainid() - } - - if (chainId == 1) { - (amountReceived, , ) = exchanger.getAmountsForAtomicExchange( - sourceAmount, - sourceCurrencyKey, - destinationCurrencyKey - ); - } else { - (amountReceived, , ) = exchanger.getAmountsForExchange( - sourceAmount, - sourceCurrencyKey, - destinationCurrencyKey - ); - } - } - - function getSynthetixAddress(IReadProxyAddressResolver readProxy) private view returns (address) { - return IAddressResolver(readProxy.target()).getAddress("Synthetix"); - } - - function getExchanger(IReadProxyAddressResolver readProxy) private view returns (IExchanger) { - return IExchanger(IAddressResolver(readProxy.target()).getAddress("Exchanger")); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/TwoHopSampler.sol b/contracts/zero-ex/contracts/test/samplers/TwoHopSampler.sol deleted file mode 100644 index f0cc3a64a9..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/TwoHopSampler.sol +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol"; - -contract TwoHopSampler { - using LibBytesV06 for bytes; - - struct HopInfo { - uint256 sourceIndex; - bytes returnData; - } - - function sampleTwoHopSell( - bytes[] memory firstHopCalls, - bytes[] memory secondHopCalls, - uint256 sellAmount - ) public returns (HopInfo memory firstHop, HopInfo memory secondHop, uint256 buyAmount) { - uint256 intermediateAssetAmount = 0; - for (uint256 i = 0; i != firstHopCalls.length; ++i) { - firstHopCalls[i].writeUint256(firstHopCalls[i].length - 32, sellAmount); - (bool didSucceed, bytes memory returnData) = address(this).call(firstHopCalls[i]); - if (didSucceed) { - uint256 amount = returnData.readUint256(returnData.length - 32); - if (amount > intermediateAssetAmount) { - intermediateAssetAmount = amount; - firstHop.sourceIndex = i; - firstHop.returnData = returnData; - } - } - } - if (intermediateAssetAmount == 0) { - return (firstHop, secondHop, buyAmount); - } - for (uint256 j = 0; j != secondHopCalls.length; ++j) { - secondHopCalls[j].writeUint256(secondHopCalls[j].length - 32, intermediateAssetAmount); - (bool didSucceed, bytes memory returnData) = address(this).call(secondHopCalls[j]); - if (didSucceed) { - uint256 amount = returnData.readUint256(returnData.length - 32); - if (amount > buyAmount) { - buyAmount = amount; - secondHop.sourceIndex = j; - secondHop.returnData = returnData; - } - } - } - } - - function sampleTwoHopBuy( - bytes[] memory firstHopCalls, - bytes[] memory secondHopCalls, - uint256 buyAmount - ) public returns (HopInfo memory firstHop, HopInfo memory secondHop, uint256 sellAmount) { - sellAmount = uint256(-1); - uint256 intermediateAssetAmount = uint256(-1); - for (uint256 j = 0; j != secondHopCalls.length; ++j) { - secondHopCalls[j].writeUint256(secondHopCalls[j].length - 32, buyAmount); - (bool didSucceed, bytes memory returnData) = address(this).call(secondHopCalls[j]); - if (didSucceed) { - uint256 amount = returnData.readUint256(returnData.length - 32); - if (amount > 0 && amount < intermediateAssetAmount) { - intermediateAssetAmount = amount; - secondHop.sourceIndex = j; - secondHop.returnData = returnData; - } - } - } - if (intermediateAssetAmount == uint256(-1)) { - return (firstHop, secondHop, sellAmount); - } - for (uint256 i = 0; i != firstHopCalls.length; ++i) { - firstHopCalls[i].writeUint256(firstHopCalls[i].length - 32, intermediateAssetAmount); - (bool didSucceed, bytes memory returnData) = address(this).call(firstHopCalls[i]); - if (didSucceed) { - uint256 amount = returnData.readUint256(returnData.length - 32); - if (amount > 0 && amount < sellAmount) { - sellAmount = amount; - firstHop.sourceIndex = i; - firstHop.returnData = returnData; - } - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/UniswapSampler.sol b/contracts/zero-ex/contracts/test/samplers/UniswapSampler.sol deleted file mode 100644 index e3fe2563b3..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/UniswapSampler.sol +++ /dev/null @@ -1,191 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -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 SamplerUtils { - /// @dev Gas limit for Uniswap calls. - uint256 private constant UNISWAP_CALL_GAS = 150e3; // 150k - - /// @dev Sample sell quotes from Uniswap. - /// @param router Address of the Uniswap Router - /// @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 makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromUniswap( - address router, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - IUniswapExchangeQuotes takerTokenExchange = takerToken == address(0) - ? IUniswapExchangeQuotes(0) - : _getUniswapExchange(router, takerToken); - IUniswapExchangeQuotes makerTokenExchange = makerToken == address(0) - ? IUniswapExchangeQuotes(0) - : _getUniswapExchange(router, makerToken); - for (uint256 i = 0; i < numSamples; i++) { - bool didSucceed = true; - if (makerToken == address(0)) { - (makerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( - address(takerTokenExchange), - takerTokenExchange.getTokenToEthInputPrice.selector, - takerTokenAmounts[i] - ); - } else if (takerToken == address(0)) { - (makerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( - address(makerTokenExchange), - makerTokenExchange.getEthToTokenInputPrice.selector, - takerTokenAmounts[i] - ); - } else { - uint256 ethBought; - (ethBought, didSucceed) = _callUniswapExchangePriceFunction( - address(takerTokenExchange), - takerTokenExchange.getTokenToEthInputPrice.selector, - takerTokenAmounts[i] - ); - if (ethBought != 0) { - (makerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( - address(makerTokenExchange), - makerTokenExchange.getEthToTokenInputPrice.selector, - ethBought - ); - } else { - makerTokenAmounts[i] = 0; - } - } - // Break early if amounts are 0 - if (!didSucceed || makerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Sample buy quotes from Uniswap. - /// @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 takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromUniswap( - address router, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - - IUniswapExchangeQuotes takerTokenExchange = takerToken == address(0) - ? IUniswapExchangeQuotes(0) - : _getUniswapExchange(router, takerToken); - IUniswapExchangeQuotes makerTokenExchange = makerToken == address(0) - ? IUniswapExchangeQuotes(0) - : _getUniswapExchange(router, makerToken); - for (uint256 i = 0; i < numSamples; i++) { - bool didSucceed = true; - if (makerToken == address(0)) { - (takerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( - address(takerTokenExchange), - takerTokenExchange.getTokenToEthOutputPrice.selector, - makerTokenAmounts[i] - ); - } else if (takerToken == address(0)) { - (takerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( - address(makerTokenExchange), - makerTokenExchange.getEthToTokenOutputPrice.selector, - makerTokenAmounts[i] - ); - } else { - uint256 ethSold; - (ethSold, didSucceed) = _callUniswapExchangePriceFunction( - address(makerTokenExchange), - makerTokenExchange.getEthToTokenOutputPrice.selector, - makerTokenAmounts[i] - ); - if (ethSold != 0) { - (takerTokenAmounts[i], didSucceed) = _callUniswapExchangePriceFunction( - address(takerTokenExchange), - takerTokenExchange.getTokenToEthOutputPrice.selector, - ethSold - ); - } else { - takerTokenAmounts[i] = 0; - } - } - // Break early if amounts are 0 - if (!didSucceed || takerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Gracefully calls a Uniswap pricing function. - /// @param uniswapExchangeAddress Address of an `IUniswapExchangeQuotes` exchange. - /// @param functionSelector Selector of the target function. - /// @param inputAmount Quantity parameter particular to the pricing function. - /// @return outputAmount The returned amount from the function call. Will be - /// zero if the call fails or if `uniswapExchangeAddress` is zero. - function _callUniswapExchangePriceFunction( - address uniswapExchangeAddress, - bytes4 functionSelector, - uint256 inputAmount - ) private view returns (uint256 outputAmount, bool didSucceed) { - if (uniswapExchangeAddress == address(0)) { - return (outputAmount, didSucceed); - } - bytes memory resultData; - (didSucceed, resultData) = uniswapExchangeAddress.staticcall.gas(UNISWAP_CALL_GAS)( - abi.encodeWithSelector(functionSelector, inputAmount) - ); - if (didSucceed) { - outputAmount = abi.decode(resultData, (uint256)); - } - } - - /// @dev Retrive an existing Uniswap exchange contract. - /// Throws if the exchange does not exist. - /// @param router Address of the Uniswap router. - /// @param tokenAddress Address of the token contract. - /// @return exchange `IUniswapExchangeQuotes` for the token. - function _getUniswapExchange( - address router, - address tokenAddress - ) private view returns (IUniswapExchangeQuotes exchange) { - exchange = IUniswapExchangeQuotes(address(IUniswapExchangeFactory(router).getExchange(tokenAddress))); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/UniswapV2Sampler.sol b/contracts/zero-ex/contracts/test/samplers/UniswapV2Sampler.sol deleted file mode 100644 index 3ca9100387..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/UniswapV2Sampler.sol +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -import "./interfaces/IUniswapV2Router01.sol"; - -contract UniswapV2Sampler { - /// @dev Gas limit for UniswapV2 calls. - uint256 private constant UNISWAPV2_CALL_GAS = 150e3; // 150k - - /// @dev Sample sell quotes from UniswapV2. - /// @param router Router to look up tokens and amounts - /// @param path Token route. Should be takerToken -> makerToken - /// @param takerTokenAmounts Taker token sell amount for each sample. - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromUniswapV2( - address router, - address[] memory path, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - try IUniswapV2Router01(router).getAmountsOut{gas: UNISWAPV2_CALL_GAS}(takerTokenAmounts[i], path) returns ( - uint256[] memory amounts - ) { - makerTokenAmounts[i] = amounts[path.length - 1]; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } - - /// @dev Sample buy quotes from UniswapV2. - /// @param router Router to look up tokens and amounts - /// @param path Token route. Should be takerToken -> makerToken. - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromUniswapV2( - address router, - address[] memory path, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - try IUniswapV2Router01(router).getAmountsIn{gas: UNISWAPV2_CALL_GAS}(makerTokenAmounts[i], path) returns ( - uint256[] memory amounts - ) { - takerTokenAmounts[i] = amounts[0]; - // Break early if there are 0 amounts - if (takerTokenAmounts[i] == 0) { - break; - } - } catch (bytes memory) { - // Swallow failures, leaving all results as zero. - break; - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/UniswapV3Sampler.sol b/contracts/zero-ex/contracts/test/samplers/UniswapV3Sampler.sol deleted file mode 100644 index 1f902a1128..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/UniswapV3Sampler.sol +++ /dev/null @@ -1,319 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; - -interface IUniswapV3QuoterV2 { - function factory() external view returns (IUniswapV3Factory factory); - - // @notice Returns the amount out received for a given exact input swap without executing the swap - // @param path The path of the swap, i.e. each token pair and the pool fee - // @param amountIn The amount of the first token to swap - // @return amountOut The amount of the last token that would be received - // @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path - // @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path - // @return gasEstimate The estimate of the gas that the swap consumes - function quoteExactInput( - bytes memory path, - uint256 amountIn - ) - external - returns ( - uint256 amountOut, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksCrossedList, - uint256 gasEstimate - ); - - // @notice Returns the amount in required for a given exact output swap without executing the swap - // @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order - // @param amountOut The amount of the last token to receive - // @return amountIn The amount of first token required to be paid - // @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path - // @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path - // @return gasEstimate The estimate of the gas that the swap consumes - function quoteExactOutput( - bytes memory path, - uint256 amountOut - ) - external - returns ( - uint256 amountIn, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksCrossedList, - uint256 gasEstimate - ); -} - -interface IUniswapV3Factory { - function getPool(IERC20TokenV06 a, IERC20TokenV06 b, uint24 fee) external view returns (IUniswapV3Pool pool); -} - -interface IUniswapV3Pool { - function token0() external view returns (IERC20TokenV06); - - function token1() external view returns (IERC20TokenV06); - - function fee() external view returns (uint24); -} - -contract UniswapV3Sampler { - /// @dev Gas limit for UniswapV3 calls. This is 100% a guess. - uint256 private constant QUOTE_GAS = 700e3; - - /// @dev Sample sell quotes from UniswapV3. - /// @param quoter UniswapV3 Quoter contract. - /// @param path Token route. Should be takerToken -> makerToken - /// @param takerTokenAmounts Taker token sell amount for each sample. - /// @return uniswapPaths The encoded uniswap path for each sample. - /// @return uniswapGasUsed Estimated amount of gas used - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromUniswapV3( - IUniswapV3QuoterV2 quoter, - IERC20TokenV06[] memory path, - uint256[] memory takerTokenAmounts - ) - public - returns (bytes[] memory uniswapPaths, uint256[] memory uniswapGasUsed, uint256[] memory makerTokenAmounts) - { - IUniswapV3Pool[][] memory poolPaths = _getValidPoolPaths(quoter.factory(), path, 0); - - makerTokenAmounts = new uint256[](takerTokenAmounts.length); - uniswapPaths = new bytes[](takerTokenAmounts.length); - uniswapGasUsed = new uint256[](takerTokenAmounts.length); - - for (uint256 i = 0; i < takerTokenAmounts.length; ++i) { - // Pick the best result from all the paths. - uint256 topBuyAmount = 0; - for (uint256 j = 0; j < poolPaths.length; ++j) { - bytes memory uniswapPath = _toUniswapPath(path, poolPaths[j]); - try quoter.quoteExactInput{gas: QUOTE_GAS}(uniswapPath, takerTokenAmounts[i]) returns ( - uint256 buyAmount, - uint160[] memory /* sqrtPriceX96AfterList */, - uint32[] memory /* initializedTicksCrossedList */, - uint256 gasUsed - ) { - if (topBuyAmount <= buyAmount) { - topBuyAmount = buyAmount; - uniswapPaths[i] = uniswapPath; - uniswapGasUsed[i] = gasUsed; - } - } catch {} - } - // Break early if we can't complete the sells. - if (topBuyAmount == 0) { - // HACK(kimpers): To avoid too many local variables, paths and gas used is set directly in the loop - // then reset if no valid valid quote was found - uniswapPaths[i] = ""; - uniswapGasUsed[i] = 0; - break; - } - makerTokenAmounts[i] = topBuyAmount; - } - } - - /// @dev Sample buy quotes from UniswapV3. - /// @param quoter UniswapV3 Quoter contract. - /// @param path Token route. Should be takerToken -> makerToken. - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return uniswapPaths The encoded uniswap path for each sample. - /// @return uniswapGasUsed Estimated amount of gas used - /// @return takerTokenAmounts Taker amounts sold at each maker token - /// amount. - function sampleBuysFromUniswapV3( - IUniswapV3QuoterV2 quoter, - IERC20TokenV06[] memory path, - uint256[] memory makerTokenAmounts - ) - public - returns (bytes[] memory uniswapPaths, uint256[] memory uniswapGasUsed, uint256[] memory takerTokenAmounts) - { - IUniswapV3Pool[][] memory poolPaths = _getValidPoolPaths(quoter.factory(), path, 0); - IERC20TokenV06[] memory reversedPath = _reverseTokenPath(path); - - takerTokenAmounts = new uint256[](makerTokenAmounts.length); - uniswapPaths = new bytes[](makerTokenAmounts.length); - uniswapGasUsed = new uint256[](makerTokenAmounts.length); - - for (uint256 i = 0; i < makerTokenAmounts.length; ++i) { - // Pick the best result from all the paths. - uint256 topSellAmount = 0; - for (uint256 j = 0; j < poolPaths.length; ++j) { - // quoter requires path to be reversed for buys. - bytes memory uniswapPath = _toUniswapPath(reversedPath, _reversePoolPath(poolPaths[j])); - try quoter.quoteExactOutput{gas: QUOTE_GAS}(uniswapPath, makerTokenAmounts[i]) returns ( - uint256 sellAmount, - uint160[] memory /* sqrtPriceX96AfterList */, - uint32[] memory /* initializedTicksCrossedList */, - uint256 gasUsed - ) { - if (topSellAmount == 0 || topSellAmount >= sellAmount) { - topSellAmount = sellAmount; - // But the output path should still be encoded for sells. - uniswapPaths[i] = _toUniswapPath(path, poolPaths[j]); - uniswapGasUsed[i] = gasUsed; - } - } catch {} - } - // Break early if we can't complete the buys. - if (topSellAmount == 0) { - // HACK(kimpers): To avoid too many local variables, paths and gas used is set directly in the loop - // then reset if no valid valid quote was found - uniswapPaths[i] = ""; - uniswapGasUsed[i] = 0; - break; - } - takerTokenAmounts[i] = topSellAmount; - } - } - - function _getValidPoolPaths( - IUniswapV3Factory factory, - IERC20TokenV06[] memory tokenPath, - uint256 startIndex - ) private view returns (IUniswapV3Pool[][] memory poolPaths) { - require(tokenPath.length - startIndex >= 2, "UniswapV3Sampler/tokenPath too short"); - uint24[4] memory validPoolFees = [ - // The launch pool fees. Could get hairier if they add more. - uint24(0.0001e6), - uint24(0.0005e6), - uint24(0.003e6), - uint24(0.01e6) - ]; - IUniswapV3Pool[] memory validPools = new IUniswapV3Pool[](validPoolFees.length); - uint256 numValidPools = 0; - { - IERC20TokenV06 inputToken = tokenPath[startIndex]; - IERC20TokenV06 outputToken = tokenPath[startIndex + 1]; - for (uint256 i = 0; i < validPoolFees.length; ++i) { - IUniswapV3Pool pool = factory.getPool(inputToken, outputToken, validPoolFees[i]); - if (_isValidPool(pool)) { - validPools[numValidPools++] = pool; - } - } - } - if (numValidPools == 0) { - // No valid pools for this hop. - return poolPaths; - } - if (startIndex + 2 == tokenPath.length) { - // End of path. - poolPaths = new IUniswapV3Pool[][](numValidPools); - for (uint256 i = 0; i < numValidPools; ++i) { - poolPaths[i] = new IUniswapV3Pool[](1); - poolPaths[i][0] = validPools[i]; - } - return poolPaths; - } - // Get paths for subsequent hops. - IUniswapV3Pool[][] memory subsequentPoolPaths = _getValidPoolPaths(factory, tokenPath, startIndex + 1); - if (subsequentPoolPaths.length == 0) { - // Could not complete the path. - return poolPaths; - } - // Combine our pools with the next hop paths. - poolPaths = new IUniswapV3Pool[][](numValidPools * subsequentPoolPaths.length); - for (uint256 i = 0; i < numValidPools; ++i) { - for (uint256 j = 0; j < subsequentPoolPaths.length; ++j) { - uint256 o = i * subsequentPoolPaths.length + j; - // Prepend pool to the subsequent path. - poolPaths[o] = new IUniswapV3Pool[](1 + subsequentPoolPaths[j].length); - poolPaths[o][0] = validPools[i]; - for (uint256 k = 0; k < subsequentPoolPaths[j].length; ++k) { - poolPaths[o][1 + k] = subsequentPoolPaths[j][k]; - } - } - } - return poolPaths; - } - - function _reverseTokenPath( - IERC20TokenV06[] memory tokenPath - ) private pure returns (IERC20TokenV06[] memory reversed) { - reversed = new IERC20TokenV06[](tokenPath.length); - for (uint256 i = 0; i < tokenPath.length; ++i) { - reversed[i] = tokenPath[tokenPath.length - i - 1]; - } - } - - function _reversePoolPath( - IUniswapV3Pool[] memory poolPath - ) private pure returns (IUniswapV3Pool[] memory reversed) { - reversed = new IUniswapV3Pool[](poolPath.length); - for (uint256 i = 0; i < poolPath.length; ++i) { - reversed[i] = poolPath[poolPath.length - i - 1]; - } - } - - function _isValidPool(IUniswapV3Pool pool) private view returns (bool isValid) { - // Check if it has been deployed. - { - uint256 codeSize; - assembly { - codeSize := extcodesize(pool) - } - if (codeSize == 0) { - return false; - } - } - // Must have a balance of both tokens. - if (pool.token0().balanceOf(address(pool)) == 0) { - return false; - } - if (pool.token1().balanceOf(address(pool)) == 0) { - return false; - } - return true; - } - - function _toUniswapPath( - IERC20TokenV06[] memory tokenPath, - IUniswapV3Pool[] memory poolPath - ) private view returns (bytes memory uniswapPath) { - require( - tokenPath.length >= 2 && tokenPath.length == poolPath.length + 1, - "UniswapV3Sampler/invalid path lengths" - ); - // Uniswap paths are tightly packed as: - // [token0, token0token1PairFee, token1, token1Token2PairFee, token2, ...] - uniswapPath = new bytes(tokenPath.length * 20 + poolPath.length * 3); - uint256 o; - assembly { - o := add(uniswapPath, 32) - } - for (uint256 i = 0; i < tokenPath.length; ++i) { - if (i > 0) { - uint24 poolFee = poolPath[i - 1].fee(); - assembly { - mstore(o, shl(232, poolFee)) - o := add(o, 3) - } - } - IERC20TokenV06 token = tokenPath[i]; - assembly { - mstore(o, shl(96, token)) - o := add(o, 20) - } - } - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/UtilitySampler.sol b/contracts/zero-ex/contracts/test/samplers/UtilitySampler.sol deleted file mode 100644 index adb4a94f93..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/UtilitySampler.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2021 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; -pragma experimental ABIEncoderV2; - -import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; - -contract UtilitySampler { - using LibERC20TokenV06 for IERC20TokenV06; - - IERC20TokenV06 private immutable UTILITY_ETH_ADDRESS = IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); - - function getTokenDecimals(IERC20TokenV06[] memory tokens) public view returns (uint256[] memory decimals) { - decimals = new uint256[](tokens.length); - for (uint256 i = 0; i != tokens.length; i++) { - decimals[i] = tokens[i] == UTILITY_ETH_ADDRESS ? 18 : tokens[i].compatDecimals(); - } - } - - function getBalanceOf( - IERC20TokenV06[] memory tokens, - address account - ) public view returns (uint256[] memory balances) { - balances = new uint256[](tokens.length); - for (uint256 i = 0; i != tokens.length; i++) { - balances[i] = tokens[i] == UTILITY_ETH_ADDRESS ? account.balance : tokens[i].compatBalanceOf(account); - } - } - - function getAllowanceOf( - IERC20TokenV06[] memory tokens, - address account, - address spender - ) public view returns (uint256[] memory allowances) { - allowances = new uint256[](tokens.length); - for (uint256 i = 0; i != tokens.length; i++) { - allowances[i] = tokens[i] == UTILITY_ETH_ADDRESS ? 0 : tokens[i].compatAllowance(account, spender); - } - } - - function isContract(address account) public view returns (bool) { - uint256 size; - assembly { - size := extcodesize(account) - } - return size > 0; - } - - function getGasLeft() public returns (uint256) { - return gasleft(); - } - - function getBlockNumber() public view returns (uint256) { - return block.number; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/VelodromeSampler.sol b/contracts/zero-ex/contracts/test/samplers/VelodromeSampler.sol deleted file mode 100644 index ee7da0aff3..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/VelodromeSampler.sol +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2022 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; -pragma experimental ABIEncoderV2; - -import "./ApproximateBuys.sol"; -import "./SamplerUtils.sol"; - -struct VeloRoute { - address from; - address to; - bool stable; -} - -interface IVelodromeRouter { - function getAmountOut( - uint256 amountIn, - address tokenIn, - address tokenOut - ) external view returns (uint256 amount, bool stable); - - function getAmountsOut( - uint256 amountIn, - VeloRoute[] calldata routes - ) external view returns (uint256[] memory amounts); -} - -contract VelodromeSampler is SamplerUtils, ApproximateBuys { - /// @dev Sample sell quotes from Velodrome - /// @param router Address of Velodrome router. - /// @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 (sorted in ascending order). - /// @return stable Whether the pool is a stable pool (vs volatile). - /// @return makerTokenAmounts Maker amounts bought at each taker token amount. - function sampleSellsFromVelodrome( - IVelodromeRouter router, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (bool stable, uint256[] memory makerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - - // Sampling should not mix stable and volatile pools. - // Find the most liquid pool based on max(takerTokenAmounts) and stick with it. - stable = _isMostLiquidPoolStablePool(router, takerToken, makerToken, takerTokenAmounts); - VeloRoute[] memory routes = new VeloRoute[](1); - routes[0] = VeloRoute({from: takerToken, to: makerToken, stable: stable}); - - for (uint256 i = 0; i < numSamples; i++) { - makerTokenAmounts[i] = router.getAmountsOut(takerTokenAmounts[i], routes)[1]; - // Break early if there are 0 amounts - if (makerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Sample buy quotes from Velodrome. - /// @param router Address of Velodrome router. - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param makerTokenAmounts Maker token buy amount for each sample. - /// @return stable Whether the pool is a stable pool (vs volatile). - /// @return takerTokenAmounts Taker amounts sold at each maker token amount. - function sampleBuysFromVelodrome( - IVelodromeRouter router, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (bool stable, uint256[] memory takerTokenAmounts) { - _assertValidPair(makerToken, takerToken); - - // Sampling should not mix stable and volatile pools. - // Find the most liquid pool based on the reverse swap (maker -> taker) and stick with it. - stable = _isMostLiquidPoolStablePool(router, makerToken, takerToken, makerTokenAmounts); - - takerTokenAmounts = _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - takerTokenData: abi.encode(router, VeloRoute({from: takerToken, to: makerToken, stable: stable})), - makerTokenData: abi.encode(router, VeloRoute({from: makerToken, to: takerToken, stable: stable})), - getSellQuoteCallback: _sampleSellForApproximateBuyFromVelodrome - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromVelodrome( - bytes memory takerTokenData, - bytes memory /* makerTokenData */, - uint256 sellAmount - ) internal view returns (uint256) { - (IVelodromeRouter router, VeloRoute memory route) = abi.decode(takerTokenData, (IVelodromeRouter, VeloRoute)); - - VeloRoute[] memory routes = new VeloRoute[](1); - routes[0] = route; - return router.getAmountsOut(sellAmount, routes)[1]; - } - - /// @dev Returns whether the most liquid pool is a stable pool. - /// @param router Address of Velodrome router. - /// @param takerToken Address of the taker token (what to sell). - /// @param makerToken Address of the maker token (what to buy). - /// @param takerTokenAmounts Taker token buy amount for each sample (sorted in ascending order) - /// @return stable Whether the pool is a stable pool (vs volatile). - function _isMostLiquidPoolStablePool( - IVelodromeRouter router, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) internal view returns (bool stable) { - uint256 numSamples = takerTokenAmounts.length; - (, stable) = router.getAmountOut(takerTokenAmounts[numSamples - 1], takerToken, makerToken); - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/WooPPSampler.sol b/contracts/zero-ex/contracts/test/samplers/WooPPSampler.sol deleted file mode 100644 index 4fbdf9bc06..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/WooPPSampler.sol +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; -import "./SamplerUtils.sol"; -import "./ApproximateBuys.sol"; - -interface IWooPP { - /// @dev get the quote token address (immutable) - /// @return address of quote token - function quoteToken() external view returns (address); - - /// @dev Query the amount for selling the base token amount. - /// @param baseToken the base token to sell - /// @param baseAmount the amount to sell - /// @return quoteAmount the swapped quote amount - function querySellBase(address baseToken, uint256 baseAmount) external view returns (uint256 quoteAmount); - - /// @dev Query the amount for selling the quote token. - /// @param baseToken the base token to receive (buy) - /// @param quoteAmount the amount to sell - /// @return baseAmount the swapped base token amount - function querySellQuote(address baseToken, uint256 quoteAmount) external view returns (uint256 baseAmount); -} - -contract WooPPSampler is SamplerUtils, ApproximateBuys { - function query( - uint amountIn, - address tokenIn, - address tokenOut, - address pool - ) internal view returns (uint256 amountOut) { - if (amountIn == 0) { - return 0; - } - address quoteToken = IWooPP(pool).quoteToken(); - if (tokenIn == quoteToken) { - amountOut = IWooPP(pool).querySellQuote(tokenOut, amountIn); - } else if (tokenOut == quoteToken) { - amountOut = IWooPP(pool).querySellBase(tokenIn, amountIn); - } else { - uint quoteAmount = IWooPP(pool).querySellBase(tokenIn, amountIn); - amountOut = IWooPP(pool).querySellQuote(tokenOut, quoteAmount); - } - } - - /// @dev Sample sell quotes from WooFI. - /// @param pool Address of the pool we are sampling from - /// @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 (sorted in ascending order). - /// @return makerTokenAmounts Maker amounts bought at each taker token - /// amount. - function sampleSellsFromWooPP( - address pool, - address takerToken, - address makerToken, - uint256[] memory takerTokenAmounts - ) public view returns (uint256[] memory makerTokenAmounts) { - uint256 numSamples = takerTokenAmounts.length; - makerTokenAmounts = new uint256[](numSamples); - for (uint256 i = 0; i < numSamples; i++) { - makerTokenAmounts[i] = query(takerTokenAmounts[i], takerToken, makerToken, pool); - - if (makerTokenAmounts[i] == 0) { - break; - } - } - } - - /// @dev Sample buy quotes from WooFI. - /// @param pool Address of the pool we are sampling from - /// @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 (sorted in ascending order). - /// @return takerTokenAmounts Taker amounts bought at each taker token - /// amount. - function sampleBuysFromWooPP( - address pool, - address takerToken, - address makerToken, - uint256[] memory makerTokenAmounts - ) public view returns (uint256[] memory takerTokenAmounts) { - uint256 numSamples = makerTokenAmounts.length; - takerTokenAmounts = _sampleApproximateBuys( - ApproximateBuyQuoteOpts({ - takerTokenData: abi.encode(pool, takerToken, makerToken), - makerTokenData: abi.encode(pool, makerToken, takerToken), - getSellQuoteCallback: _sampleSellForApproximateBuyFromWoofi - }), - makerTokenAmounts - ); - } - - function _sampleSellForApproximateBuyFromWoofi( - bytes memory takerTokenData, - bytes memory makerTokenData, - uint256 sellAmount - ) internal view returns (uint256) { - (address _pool, address _takerToken, address _makerToken) = abi.decode( - takerTokenData, - (address, address, address) - ); - (bool success, bytes memory resultData) = address(this).staticcall( - abi.encodeWithSelector( - this.sampleSellsFromWooPP.selector, - _pool, - _takerToken, - _makerToken, - _toSingleValueArray(sellAmount) - ) - ); - if (!success) { - return 0; - } - return abi.decode(resultData, (uint256[]))[0]; - } -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IBalancer.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IBalancer.sol deleted file mode 100644 index c3bd3de34e..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IBalancer.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IBalancer { - function isBound(address t) external view returns (bool); - - function getDenormalizedWeight(address token) external view returns (uint256); - - function getBalance(address token) external view returns (uint256); - - function getSwapFee() external view returns (uint256); - - function calcOutGivenIn( - uint256 tokenBalanceIn, - uint256 tokenWeightIn, - uint256 tokenBalanceOut, - uint256 tokenWeightOut, - uint256 tokenAmountIn, - uint256 swapFee - ) external pure returns (uint256 tokenAmountOut); - - function calcInGivenOut( - uint256 tokenBalanceIn, - uint256 tokenWeightIn, - uint256 tokenBalanceOut, - uint256 tokenWeightOut, - uint256 tokenAmountOut, - uint256 swapFee - ) external pure returns (uint256 tokenAmountIn); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IBalancerV2Vault.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IBalancerV2Vault.sol deleted file mode 100644 index 1c48ebbc32..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IBalancerV2Vault.sol +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -/// @dev Minimal Balancer V2 Vault interface -/// for documentation refer to https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/vault/interfaces/IVault.sol -interface IBalancerV2Vault { - enum SwapKind { - GIVEN_IN, - GIVEN_OUT - } - - struct BatchSwapStep { - bytes32 poolId; - uint256 assetInIndex; - uint256 assetOutIndex; - uint256 amount; - bytes userData; - } - - struct FundManagement { - address sender; - bool fromInternalBalance; - address payable recipient; - bool toInternalBalance; - } - - struct BalancerV2PoolInfo { - bytes32 poolId; - address vault; - } - - function queryBatchSwap( - SwapKind kind, - BatchSwapStep[] calldata swaps, - address[] calldata assets, - FundManagement calldata funds - ) external returns (int256[] memory assetDeltas); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IBancor.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IBancor.sol deleted file mode 100644 index 0acda43dd4..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IBancor.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IBancor {} - -interface IBancorNetwork { - function conversionPath(address _sourceToken, address _targetToken) external view returns (address[] memory); - - function rateByPath(address[] memory _path, uint256 _amount) external view returns (uint256); -} - -interface IBancorRegistry { - function getAddress(bytes32 _contractName) external view returns (address); - - function BANCOR_NETWORK() external view returns (bytes32); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IBancorV3.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IBancorV3.sol deleted file mode 100644 index 0c8da5c26b..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IBancorV3.sol +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2022 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; -pragma experimental ABIEncoderV2; - -interface IBancorV3 { - /** - * @dev returns the output amount when trading by providing the source amount - */ - function tradeOutputBySourceAmount( - address sourceToken, - address targetToken, - uint256 sourceAmount - ) external view returns (uint256); - - /** - * @dev returns the input amount when trading by providing the target amount - */ - function tradeInputByTargetAmount( - address sourceToken, - address targetToken, - uint256 targetAmount - ) external view returns (uint256); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/ICurve.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/ICurve.sol deleted file mode 100644 index dd19e7b363..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/ICurve.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -// solhint-disable func-name-mixedcase -interface ICurve { - /// @dev Sell `sellAmount` of `fromToken` token and receive `toToken` token. - /// This function exists on later versions of Curve (USDC/DAI/USDT) - /// @param i The token index being sold. - /// @param j The token index being bought. - /// @param sellAmount The amount of token being bought. - /// @param minBuyAmount The minimum buy amount of the token being bought. - function exchange_underlying(int128 i, int128 j, uint256 sellAmount, uint256 minBuyAmount) external; - - /// @dev Get the amount of `toToken` by selling `sellAmount` of `fromToken` - /// @param i The token index being sold. - /// @param j The token index being bought. - /// @param sellAmount The amount of token being bought. - function get_dy_underlying(int128 i, int128 j, uint256 sellAmount) external returns (uint256 dy); - - /// @dev Get the amount of `fromToken` by buying `buyAmount` of `toToken` - /// This function exists on later versions of Curve (USDC/DAI/USDT) - /// @param i The token index being sold. - /// @param j The token index being bought. - /// @param buyAmount The amount of token being bought. - function get_dx_underlying(int128 i, int128 j, uint256 buyAmount) external returns (uint256 dx); - - /// @dev Get the underlying token address from the token index - /// @param i The token index. - function underlying_coins(int128 i) external returns (address tokenAddress); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IGMX.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IGMX.sol deleted file mode 100644 index 21a3a6c4d2..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IGMX.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma solidity ^0.6; -pragma experimental ABIEncoderV2; - -interface IGMX { - function getMaxAmountIn(IVault _vault, address _tokenIn, address _tokenOut) external view returns (uint256); - - function getAmountOut( - IVault _vault, - address _tokenIn, - address _tokenOut, - uint256 _amountIn - ) external view returns (uint256, uint256); -} - -interface IVault { - function getFeeBasisPoints( - address _token, - uint256 _usdgDelta, - uint256 _feeBasisPoints, - uint256 _taxBasisPoints, - bool _increment - ) external view returns (uint256); - - function stableSwapFeeBasisPoints() external view returns (uint256); - - function stableTokens(address _token) external view returns (bool); - - function tokenDecimals(address _token) external view returns (uint256); - - function getMaxPrice(address _token) external view returns (uint256); - - function getMinPrice(address _token) external view returns (uint256); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IMStable.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IMStable.sol deleted file mode 100644 index 2173869418..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IMStable.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IMStable { - function getSwapOutput( - address _input, - address _output, - uint256 _quantity - ) external view returns (uint256 swapOutput); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IMooniswap.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IMooniswap.sol deleted file mode 100644 index d79cef57d6..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IMooniswap.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IMooniswapRegistry { - function pools(address token1, address token2) external view returns (address); -} - -interface IMooniswap { - function getReturn( - address fromToken, - address destToken, - uint256 amount - ) external view returns (uint256 returnAmount); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IMultiBridge.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IMultiBridge.sol deleted file mode 100644 index e84bd1b492..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IMultiBridge.sol +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IMultiBridge { - /// @dev Transfers `amount` of the ERC20 `tokenAddress` from `from` to `to`. - /// @param tokenAddress The address of the ERC20 token to transfer. - /// @param from Address to transfer asset from. - /// @param to Address to transfer asset to. - /// @param amount Amount of asset to transfer. - /// @param bridgeData Arbitrary asset data needed by the bridge contract. - /// @return success The magic bytes `0xdc1600f3` if successful. - function bridgeTransferFrom( - address tokenAddress, - address from, - address to, - uint256 amount, - bytes calldata bridgeData - ) external returns (bytes4 success); - - /// @dev Quotes the amount of `makerToken` that would be obtained by - /// selling `sellAmount` of `takerToken`. - /// @param takerToken Address of the taker token (what to sell). - /// @param intermediateToken The address of the intermediate token to - /// use in an indirect route. - /// @param makerToken Address of the maker token (what to buy). - /// @param sellAmount Amount of `takerToken` to sell. - /// @return makerTokenAmount Amount of `makerToken` that would be obtained. - function getSellQuote( - address takerToken, - address intermediateToken, - address makerToken, - uint256 sellAmount - ) external view returns (uint256 makerTokenAmount); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IPlatypus.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IPlatypus.sol deleted file mode 100644 index 3d21960679..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IPlatypus.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.6; - -interface IPlatypus { - function quotePotentialSwap( - address fromToken, - address toToken, - uint256 fromAmount - ) external view returns (uint256 potentialOutcome, uint256 haircut); - - function assetOf(address token) external view returns (address); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IShell.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IShell.sol deleted file mode 100644 index 9dc8042ccf..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IShell.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IShell { - function viewOriginSwap(address from, address to, uint256 fromAmount) external view returns (uint256 toAmount); - - function viewTargetSwap(address from, address to, uint256 toAmount) external view returns (uint256 fromAmount); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IUniswapExchangeQuotes.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IUniswapExchangeQuotes.sol deleted file mode 100644 index 6ad0ae75dc..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IUniswapExchangeQuotes.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IUniswapExchangeQuotes { - function getEthToTokenInputPrice(uint256 ethSold) external view returns (uint256 tokensBought); - - function getEthToTokenOutputPrice(uint256 tokensBought) external view returns (uint256 ethSold); - - function getTokenToEthInputPrice(uint256 tokensSold) external view returns (uint256 ethBought); - - function getTokenToEthOutputPrice(uint256 ethBought) external view returns (uint256 tokensSold); -} diff --git a/contracts/zero-ex/contracts/test/samplers/interfaces/IUniswapV2Router01.sol b/contracts/zero-ex/contracts/test/samplers/interfaces/IUniswapV2Router01.sol deleted file mode 100644 index 6c27223c6e..0000000000 --- a/contracts/zero-ex/contracts/test/samplers/interfaces/IUniswapV2Router01.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - - Copyright 2020 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity ^0.6; - -interface IUniswapV2Router01 { - function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); - - function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); -}