@0x/contracts-erc20-bridge-sampler
: Fix kyber bug and add test contract.
This commit is contained in:
parent
a26c3036a7
commit
d02db3864e
@ -67,11 +67,4 @@ interface IUniswapExchange {
|
||||
)
|
||||
external
|
||||
returns (uint256 tokensBought);
|
||||
|
||||
/// @dev Retrieves the token that is associated with this exchange.
|
||||
/// @return tokenAddress The token address.
|
||||
function toTokenAddress()
|
||||
external
|
||||
view
|
||||
returns (address tokenAddress);
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "./IEth2Dai.sol";
|
||||
import "./IKyberNetwork.sol";
|
||||
|
||||
|
||||
contract DeploymentConstants {
|
||||
|
||||
address constant public EXCHANGE_ADDRESS = 0x080bf510FCbF18b91105470639e9561022937712;
|
||||
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
|
||||
address constant public UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||
address constant public KYBER_NETWORK_PROXY_ADDRESS = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755;
|
||||
address constant public WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
address constant public KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
/// @dev An overridable way to retrieve the 0x Exchange contract.
|
||||
/// @return zeroex The 0x Exchange contract.
|
||||
function _getExchangeContract()
|
||||
internal
|
||||
view
|
||||
returns (IExchange zeroex)
|
||||
{
|
||||
return IExchange(EXCHANGE_ADDRESS);
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Eth2Dai exchange contract.
|
||||
/// @return eth2dai The Eth2Dai exchange contract.
|
||||
function _getEth2DaiContract()
|
||||
internal
|
||||
view
|
||||
returns (IEth2Dai eth2dai)
|
||||
{
|
||||
return IEth2Dai(ETH2DAI_ADDRESS);
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Uniswap exchange factory contract.
|
||||
/// @return uniswap The UniswapExchangeFactory contract.
|
||||
function _getUniswapExchangeFactoryContract()
|
||||
internal
|
||||
view
|
||||
returns (IUniswapExchangeFactory uniswap)
|
||||
{
|
||||
return IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS);
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Kyber network proxy contract.
|
||||
/// @return kyber The KyberNeworkProxy contract.
|
||||
function _getKyberNetworkContract()
|
||||
internal
|
||||
view
|
||||
returns (IKyberNetwork kyber)
|
||||
{
|
||||
return IKyberNetwork(KYBER_NETWORK_PROXY_ADDRESS);
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the WETH contract address.
|
||||
/// @return weth The WETH contract address.
|
||||
function _getWETHAddress()
|
||||
internal
|
||||
view
|
||||
returns (address weth)
|
||||
{
|
||||
return WETH_ADDRESS;
|
||||
}
|
||||
}
|
@ -1,25 +1,40 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "./IERC20BridgeSampler.sol";
|
||||
import "./IExchange.sol";
|
||||
import "./IEth2Dai.sol";
|
||||
import "./IKyberNetwork.sol";
|
||||
import "./IUniswapExchangeQuotes.sol";
|
||||
import "./DeploymentConstants.sol";
|
||||
|
||||
|
||||
contract ERC20BridgeSampler is
|
||||
IERC20BridgeSampler
|
||||
IERC20BridgeSampler,
|
||||
DeploymentConstants
|
||||
{
|
||||
bytes4 constant internal ERC20_PROXY_ID = bytes4(keccak256("ERC20Token(address)"));
|
||||
address constant public EXCHANGE_ADDRESS = 0x080bf510FCbF18b91105470639e9561022937712; // V2
|
||||
address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;
|
||||
address constant public UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
||||
address constant public KYBER_NETWORK_PROXY_ADDRESS = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755;
|
||||
address constant public WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
||||
address constant public KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
/// @dev Query native orders and sample sell quotes on multiple DEXes at once.
|
||||
/// @param orders Native orders to query.
|
||||
@ -30,14 +45,14 @@ contract ERC20BridgeSampler is
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleSells(
|
||||
IExchange.Order[] memory orders,
|
||||
LibOrder.Order[] memory orders,
|
||||
address[] memory sources,
|
||||
uint256[] memory takerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (
|
||||
IExchange.OrderInfo[] memory orderInfos,
|
||||
LibOrder.OrderInfo[] memory orderInfos,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
)
|
||||
{
|
||||
@ -60,14 +75,14 @@ contract ERC20BridgeSampler is
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleBuys(
|
||||
IExchange.Order[] memory orders,
|
||||
LibOrder.Order[] memory orders,
|
||||
address[] memory sources,
|
||||
uint256[] memory makerTokenAmounts
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (
|
||||
IExchange.OrderInfo[] memory orderInfos,
|
||||
LibOrder.OrderInfo[] memory orderInfos,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
)
|
||||
{
|
||||
@ -83,15 +98,15 @@ contract ERC20BridgeSampler is
|
||||
/// @dev Queries the status of several native orders.
|
||||
/// @param orders Native orders to query.
|
||||
/// @return orderInfos Order info for each respective order.
|
||||
function queryOrders(IExchange.Order[] memory orders)
|
||||
function queryOrders(LibOrder.Order[] memory orders)
|
||||
public
|
||||
view
|
||||
returns (IExchange.OrderInfo[] memory orderInfos)
|
||||
returns (LibOrder.OrderInfo[] memory orderInfos)
|
||||
{
|
||||
uint256 numOrders = orders.length;
|
||||
orderInfos = new IExchange.OrderInfo[](numOrders);
|
||||
orderInfos = new LibOrder.OrderInfo[](numOrders);
|
||||
for (uint256 i = 0; i < numOrders; i++) {
|
||||
orderInfos[i] = IExchange(EXCHANGE_ADDRESS).getOrderInfo(orders[i]);
|
||||
orderInfos[i] = _getExchangeContract().getOrderInfo(orders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,14 +185,14 @@ contract ERC20BridgeSampler is
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
address _takerToken = takerToken == WETH_ADDRESS ? KYBER_ETH_ADDRESS : takerToken;
|
||||
address _makerToken = makerToken == WETH_ADDRESS ? KYBER_ETH_ADDRESS : makerToken;
|
||||
address _takerToken = takerToken == _getWETHAddress() ? KYBER_ETH_ADDRESS : takerToken;
|
||||
address _makerToken = makerToken == _getWETHAddress() ? KYBER_ETH_ADDRESS : makerToken;
|
||||
uint256 takerTokenDecimals = LibERC20Token.decimals(takerToken);
|
||||
uint256 makerTokenDecimals = LibERC20Token.decimals(makerToken);
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
(uint256 rate,) = IKyberNetwork(KYBER_NETWORK_PROXY_ADDRESS).getExpectedRate(
|
||||
(uint256 rate,) = _getKyberNetworkContract().getExpectedRate(
|
||||
_takerToken,
|
||||
_makerToken,
|
||||
takerTokenAmounts[i]
|
||||
@ -185,8 +200,9 @@ contract ERC20BridgeSampler is
|
||||
makerTokenAmounts[i] =
|
||||
rate *
|
||||
takerTokenAmounts[i] *
|
||||
makerTokenDecimals /
|
||||
(10 ** 18 * takerTokenDecimals);
|
||||
10 ** makerTokenDecimals /
|
||||
10 ** takerTokenDecimals /
|
||||
10 ** 18;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +224,7 @@ contract ERC20BridgeSampler is
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
makerTokenAmounts[i] = IEth2Dai(ETH2DAI_ADDRESS).getBuyAmount(
|
||||
makerTokenAmounts[i] = _getEth2DaiContract().getBuyAmount(
|
||||
makerToken,
|
||||
takerToken,
|
||||
takerTokenAmounts[i]
|
||||
@ -234,7 +250,7 @@ contract ERC20BridgeSampler is
|
||||
uint256 numSamples = makerTokenAmounts.length;
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
takerTokenAmounts[i] = IEth2Dai(ETH2DAI_ADDRESS).getPayAmount(
|
||||
takerTokenAmounts[i] = _getEth2DaiContract().getPayAmount(
|
||||
takerToken,
|
||||
makerToken,
|
||||
makerTokenAmounts[i]
|
||||
@ -259,16 +275,16 @@ contract ERC20BridgeSampler is
|
||||
{
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
IUniswapExchangeQuotes takerTokenExchange = takerToken == WETH_ADDRESS ?
|
||||
IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWETHAddress() ?
|
||||
IUniswapExchangeQuotes(0) : _getUniswapExchange(takerToken);
|
||||
IUniswapExchangeQuotes makerTokenExchange = makerToken == WETH_ADDRESS ?
|
||||
IUniswapExchangeQuotes makerTokenExchange = makerToken == _getWETHAddress() ?
|
||||
IUniswapExchangeQuotes(0) : _getUniswapExchange(makerToken);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
if (makerToken == WETH_ADDRESS) {
|
||||
if (makerToken == _getWETHAddress()) {
|
||||
makerTokenAmounts[i] = takerTokenExchange.getTokenToEthInputPrice(
|
||||
takerTokenAmounts[i]
|
||||
);
|
||||
} else if (takerToken == WETH_ADDRESS) {
|
||||
} else if (takerToken == _getWETHAddress()) {
|
||||
makerTokenAmounts[i] = makerTokenExchange.getEthToTokenInputPrice(
|
||||
takerTokenAmounts[i]
|
||||
);
|
||||
@ -300,16 +316,16 @@ contract ERC20BridgeSampler is
|
||||
{
|
||||
uint256 numSamples = makerTokenAmounts.length;
|
||||
takerTokenAmounts = new uint256[](numSamples);
|
||||
IUniswapExchangeQuotes takerTokenExchange = takerToken == WETH_ADDRESS ?
|
||||
IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWETHAddress() ?
|
||||
IUniswapExchangeQuotes(0) : _getUniswapExchange(takerToken);
|
||||
IUniswapExchangeQuotes makerTokenExchange = makerToken == WETH_ADDRESS ?
|
||||
IUniswapExchangeQuotes makerTokenExchange = makerToken == _getWETHAddress() ?
|
||||
IUniswapExchangeQuotes(0) : _getUniswapExchange(makerToken);
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
if (makerToken == WETH_ADDRESS) {
|
||||
if (makerToken == _getWETHAddress()) {
|
||||
takerTokenAmounts[i] = takerTokenExchange.getTokenToEthOutputPrice(
|
||||
makerTokenAmounts[i]
|
||||
);
|
||||
} else if (takerToken == WETH_ADDRESS) {
|
||||
} else if (takerToken == _getWETHAddress()) {
|
||||
takerTokenAmounts[i] = makerTokenExchange.getEthToTokenOutputPrice(
|
||||
makerTokenAmounts[i]
|
||||
);
|
||||
@ -340,13 +356,13 @@ contract ERC20BridgeSampler is
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
if (source == ETH2DAI_ADDRESS) {
|
||||
if (source == address(_getEth2DaiContract())) {
|
||||
return sampleSellFromEth2Dai(takerToken, makerToken, takerTokenAmounts);
|
||||
}
|
||||
if (source == UNISWAP_EXCHANGE_FACTORY_ADDRESS) {
|
||||
if (source == address(_getUniswapExchangeFactoryContract())) {
|
||||
return sampleSellFromUniswap(takerToken, makerToken, takerTokenAmounts);
|
||||
}
|
||||
if (source == KYBER_NETWORK_PROXY_ADDRESS) {
|
||||
if (source == address(_getKyberNetworkContract())) {
|
||||
return sampleSellFromKyberNetwork(takerToken, makerToken, takerTokenAmounts);
|
||||
}
|
||||
revert("UNSUPPORTED_SOURCE");
|
||||
@ -368,10 +384,10 @@ contract ERC20BridgeSampler is
|
||||
view
|
||||
returns (uint256[] memory takerTokenAmounts)
|
||||
{
|
||||
if (source == ETH2DAI_ADDRESS) {
|
||||
if (source == address(_getEth2DaiContract())) {
|
||||
return sampleBuyFromEth2Dai(takerToken, makerToken, makerTokenAmounts);
|
||||
}
|
||||
if (source == UNISWAP_EXCHANGE_FACTORY_ADDRESS) {
|
||||
if (source == address(_getUniswapExchangeFactoryContract())) {
|
||||
return sampleBuyFromUniswap(takerToken, makerToken, makerTokenAmounts);
|
||||
}
|
||||
revert("UNSUPPORTED_SOURCE");
|
||||
@ -387,10 +403,7 @@ contract ERC20BridgeSampler is
|
||||
returns (IUniswapExchangeQuotes exchange)
|
||||
{
|
||||
exchange = IUniswapExchangeQuotes(
|
||||
address(
|
||||
IUniswapExchangeFactory(UNISWAP_EXCHANGE_FACTORY_ADDRESS)
|
||||
.getExchange(tokenAddress)
|
||||
)
|
||||
address(_getUniswapExchangeFactoryContract().getExchange(tokenAddress))
|
||||
);
|
||||
require(address(exchange) != address(0), "UNSUPPORTED_UNISWAP_EXCHANGE");
|
||||
}
|
||||
|
@ -1,7 +1,26 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./IExchange.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
|
||||
|
||||
interface IERC20BridgeSampler {
|
||||
@ -15,14 +34,14 @@ interface IERC20BridgeSampler {
|
||||
/// each taker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleSells(
|
||||
IExchange.Order[] calldata orders,
|
||||
LibOrder.Order[] calldata orders,
|
||||
address[] calldata sources,
|
||||
uint256[] calldata takerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
IExchange.OrderInfo[] memory orderInfos,
|
||||
LibOrder.OrderInfo[] memory orderInfos,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
);
|
||||
|
||||
@ -35,24 +54,24 @@ interface IERC20BridgeSampler {
|
||||
/// each maker token amount. First indexed by source index, then sample
|
||||
/// index.
|
||||
function queryOrdersAndSampleBuys(
|
||||
IExchange.Order[] calldata orders,
|
||||
LibOrder.Order[] calldata orders,
|
||||
address[] calldata sources,
|
||||
uint256[] calldata makerTokenAmounts
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
IExchange.OrderInfo[] memory orderInfos,
|
||||
LibOrder.OrderInfo[] memory orderInfos,
|
||||
uint256[][] memory makerTokenAmountsBySource
|
||||
);
|
||||
|
||||
/// @dev Queries the status of several native orders.
|
||||
/// @param orders Native orders to query.
|
||||
/// @return orderInfos Order info for each respective order.
|
||||
function queryOrders(IExchange.Order[] calldata orders)
|
||||
function queryOrders(LibOrder.Order[] calldata orders)
|
||||
external
|
||||
view
|
||||
returns (IExchange.OrderInfo[] memory orderInfos);
|
||||
returns (LibOrder.OrderInfo[] memory orderInfos);
|
||||
|
||||
/// @dev Sample sell quotes on multiple DEXes at once.
|
||||
/// @param sources Address of each DEX. Passing in an unsupported DEX will throw.
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
interface IExchange {
|
||||
|
||||
struct Order {
|
||||
address makerAddress;
|
||||
address takerAddress;
|
||||
address feeRecipientAddress;
|
||||
address senderAddress;
|
||||
uint256 makerAssetAmount;
|
||||
uint256 takerAssetAmount;
|
||||
uint256 makerFee;
|
||||
uint256 takerFee;
|
||||
uint256 expirationTimeSeconds;
|
||||
uint256 salt;
|
||||
bytes makerAssetData;
|
||||
bytes takerAssetData;
|
||||
// bytes makerFeeAssetData;
|
||||
// bytes takerFeeAssetData;
|
||||
}
|
||||
|
||||
struct OrderInfo {
|
||||
uint8 orderStatus;
|
||||
bytes32 orderHash;
|
||||
uint256 orderTakerAssetFilledAmount;
|
||||
}
|
||||
|
||||
function getOrderInfo(Order calldata order)
|
||||
external
|
||||
view
|
||||
returns (OrderInfo memory orderInfo);
|
||||
}
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
|
@ -0,0 +1,320 @@
|
||||
/*
|
||||
|
||||
Copyright 2019 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IUniswapExchangeFactory.sol";
|
||||
import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "../src/ERC20BridgeSampler.sol";
|
||||
import "../src/IEth2Dai.sol";
|
||||
import "../src/IKyberNetwork.sol";
|
||||
|
||||
|
||||
library LibDeterministicQuotes {
|
||||
|
||||
uint256 private constant MAX_RATE = 10 ** 20;
|
||||
uint256 private constant MIN_RATE = 10 ** 16;
|
||||
|
||||
function getDeterministicSellQuote(
|
||||
bytes32 salt,
|
||||
address sellToken,
|
||||
address buyToken,
|
||||
uint256 sellAmount
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
uint256 sellBase = 10 ** getDeterministicTokenDecimals(sellToken);
|
||||
uint256 buyBase = 10 ** getDeterministicTokenDecimals(buyToken);
|
||||
uint256 rate = _getDeterministicRate(salt, sellToken, buyToken);
|
||||
return sellAmount * rate * buyBase / sellBase / 10 ** 18;
|
||||
}
|
||||
|
||||
function getDeterministicBuyQuote(
|
||||
bytes32 salt,
|
||||
address sellToken,
|
||||
address buyToken,
|
||||
uint256 buyAmount
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (uint256 sellAmount)
|
||||
{
|
||||
uint256 sellBase = 10 ** getDeterministicTokenDecimals(sellToken);
|
||||
uint256 buyBase = 10 ** getDeterministicTokenDecimals(buyToken);
|
||||
uint256 rate = _getDeterministicRate(salt, sellToken, buyToken);
|
||||
return buyAmount * 10 ** 18 * sellBase / rate / buyBase;
|
||||
}
|
||||
|
||||
function getDeterministicTokenDecimals(address token)
|
||||
internal
|
||||
pure
|
||||
returns (uint8 decimals)
|
||||
{
|
||||
bytes32 seed = keccak256(abi.encodePacked(token));
|
||||
return uint8(uint256(seed) % 18) + 6;
|
||||
}
|
||||
|
||||
function _getDeterministicRate(bytes32 salt, address sellToken, address buyToken)
|
||||
private
|
||||
pure
|
||||
returns (uint256 rate)
|
||||
{
|
||||
bytes32 seed = keccak256(abi.encodePacked(salt, sellToken, buyToken));
|
||||
return MIN_RATE + uint256(seed) % MAX_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract TestERC20BridgeSamplerUniswapExchange is
|
||||
IUniswapExchangeQuotes
|
||||
{
|
||||
bytes32 constant private BASE_SALT = 0x1d6a6a0506b0b4a554b907a4c29d9f4674e461989d9c1921feb17b26716385ab;
|
||||
|
||||
address public tokenAddress;
|
||||
bytes32 public salt;
|
||||
address private _wethAddress;
|
||||
|
||||
constructor(address _tokenAddress) public {
|
||||
_wethAddress = msg.sender;
|
||||
tokenAddress = _tokenAddress;
|
||||
salt = keccak256(abi.encodePacked(BASE_SALT, _tokenAddress));
|
||||
}
|
||||
|
||||
// Deterministic `IUniswapExchangeQuotes.getEthToTokenInputPrice()`.
|
||||
function getEthToTokenInputPrice(
|
||||
uint256 ethSold
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 tokensBought)
|
||||
{
|
||||
return LibDeterministicQuotes.getDeterministicSellQuote(
|
||||
salt,
|
||||
_wethAddress,
|
||||
tokenAddress,
|
||||
ethSold
|
||||
);
|
||||
}
|
||||
|
||||
// Deterministic `IUniswapExchangeQuotes.getEthToTokenOutputPrice()`.
|
||||
function getEthToTokenOutputPrice(
|
||||
uint256 tokensBought
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 ethSold)
|
||||
{
|
||||
return LibDeterministicQuotes.getDeterministicBuyQuote(
|
||||
salt,
|
||||
_wethAddress,
|
||||
tokenAddress,
|
||||
tokensBought
|
||||
);
|
||||
}
|
||||
|
||||
// Deterministic `IUniswapExchangeQuotes.getTokenToEthInputPrice()`.
|
||||
function getTokenToEthInputPrice(
|
||||
uint256 tokensSold
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 ethBought)
|
||||
{
|
||||
return LibDeterministicQuotes.getDeterministicSellQuote(
|
||||
salt,
|
||||
tokenAddress,
|
||||
_wethAddress,
|
||||
tokensSold
|
||||
);
|
||||
}
|
||||
|
||||
// Deterministic `IUniswapExchangeQuotes.getTokenToEthOutputPrice()`.
|
||||
function getTokenToEthOutputPrice(
|
||||
uint256 ethBought
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 tokensSold)
|
||||
{
|
||||
return LibDeterministicQuotes.getDeterministicBuyQuote(
|
||||
salt,
|
||||
tokenAddress,
|
||||
_wethAddress,
|
||||
ethBought
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract TestERC20BridgeSampler is
|
||||
ERC20BridgeSampler
|
||||
{
|
||||
bytes32 constant private KYBER_SALT = 0x0ff3ca9d46195c39f9a12afb74207b4970349fb3cfb1e459bbf170298d326bc7;
|
||||
bytes32 constant private ETH2DAI_SALT = 0xb713b61bb9bb2958a0f5d1534b21e94fc68c4c0c034b0902ed844f2f6cd1b4f7;
|
||||
|
||||
mapping (address => IUniswapExchangeQuotes) private _uniswapExchangesByToken;
|
||||
|
||||
// Creates Uniswap exchange contracts for tokens.
|
||||
function createTokenExchanges(address[] calldata tokenAddresses)
|
||||
external
|
||||
{
|
||||
for (uint256 i = 0; i < tokenAddresses.length; i++) {
|
||||
address tokenAddress = tokenAddresses[i];
|
||||
_uniswapExchangesByToken[tokenAddress] =
|
||||
new TestERC20BridgeSamplerUniswapExchange(tokenAddress);
|
||||
}
|
||||
}
|
||||
|
||||
// `IERC20.decimals()` (for WETH).
|
||||
function decimals()
|
||||
external
|
||||
view
|
||||
returns (uint8 decimalPlaces)
|
||||
{
|
||||
return 18;
|
||||
}
|
||||
|
||||
// Deterministic `IKyberNetwork.getExpectedRate()`.
|
||||
function getExpectedRate(
|
||||
address fromToken,
|
||||
address toToken,
|
||||
uint256 fromAmount
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 expectedRate, uint256 slippageRate)
|
||||
{
|
||||
uint256 quote = LibDeterministicQuotes.getDeterministicSellQuote(
|
||||
KYBER_SALT,
|
||||
fromToken,
|
||||
toToken,
|
||||
fromAmount
|
||||
);
|
||||
expectedRate =
|
||||
10 ** 18 *
|
||||
(quote / LibDeterministicQuotes.getDeterministicTokenDecimals(toToken)) /
|
||||
(fromAmount * LibDeterministicQuotes.getDeterministicTokenDecimals(fromToken));
|
||||
}
|
||||
|
||||
// Deterministic `IEth2Dai.getBuyAmount()`.
|
||||
function getBuyAmount(
|
||||
address buyToken,
|
||||
address payToken,
|
||||
uint256 payAmount
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
return LibDeterministicQuotes.getDeterministicSellQuote(
|
||||
ETH2DAI_SALT,
|
||||
payToken,
|
||||
buyToken,
|
||||
payAmount
|
||||
);
|
||||
}
|
||||
|
||||
// Deterministic `IEth2Dai.getPayAmount()`.
|
||||
function getPayAmount(
|
||||
address payToken,
|
||||
address buyToken,
|
||||
uint256 buyAmount
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (uint256 payAmount)
|
||||
{
|
||||
return LibDeterministicQuotes.getDeterministicBuyQuote(
|
||||
ETH2DAI_SALT,
|
||||
payToken,
|
||||
buyToken,
|
||||
buyAmount
|
||||
);
|
||||
}
|
||||
|
||||
// `IUniswapExchangeFactory.getExchange()`.
|
||||
function getExchange(address tokenAddress)
|
||||
external
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return address(_uniswapExchangesByToken[tokenAddress]);
|
||||
}
|
||||
|
||||
// `IExchange.getOrderInfo()`, overridden to return deterministic order infos.
|
||||
function getOrderInfo(LibOrder.Order memory order)
|
||||
public
|
||||
view
|
||||
returns (LibOrder.OrderInfo memory orderInfo)
|
||||
{
|
||||
// The order hash is just the hash of the salt.
|
||||
bytes32 orderHash = keccak256(abi.encode(order.salt));
|
||||
// Everything else is derived from the hash.
|
||||
orderInfo.orderHash = orderHash;
|
||||
orderInfo.orderStatus = uint8(uint256(orderHash) % uint8(-1));
|
||||
orderInfo.orderTakerAssetFilledAmount = uint256(orderHash) % order.takerAssetAmount;
|
||||
}
|
||||
|
||||
// Overriden to point to this contract.
|
||||
function _getExchangeContract()
|
||||
internal
|
||||
view
|
||||
returns (IExchange zeroex)
|
||||
{
|
||||
return IExchange(address(this));
|
||||
}
|
||||
|
||||
// Overriden to point to this contract.
|
||||
function _getEth2DaiContract()
|
||||
internal
|
||||
view
|
||||
returns (IEth2Dai eth2dai)
|
||||
{
|
||||
return IEth2Dai(address(this));
|
||||
}
|
||||
|
||||
// Overriden to point to this contract.
|
||||
function _getUniswapExchangeFactoryContract()
|
||||
internal
|
||||
view
|
||||
returns (IUniswapExchangeFactory uniswap)
|
||||
{
|
||||
return IUniswapExchangeFactory(address(this));
|
||||
}
|
||||
|
||||
// Overriden to point to this contract.
|
||||
function _getKyberNetworkContract()
|
||||
internal
|
||||
view
|
||||
returns (IKyberNetwork kyber)
|
||||
{
|
||||
return IKyberNetwork(address(this));
|
||||
}
|
||||
|
||||
// Overriden to point to this contract.
|
||||
function _getWETHAddress()
|
||||
internal
|
||||
view
|
||||
returns (address weth)
|
||||
{
|
||||
return address(this);
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "ERC20BridgeSampler,IERC20BridgeSampler",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(ERC20BridgeSampler|IERC20BridgeSampler|IEth2Dai|IExchange|IKyberNetwork|IUniswapExchangeQuotes|LibERC20Token).json"
|
||||
"abis": "./test/generated-artifacts/@(DeploymentConstants|ERC20BridgeSampler|IERC20BridgeSampler|IEth2Dai|IKyberNetwork|IUniswapExchangeQuotes|LibERC20Token|TestERC20BridgeSampler).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -54,6 +54,7 @@
|
||||
"@0x/contracts-asset-proxy": "^2.3.0-beta.1",
|
||||
"@0x/contracts-erc20": "^2.3.0-beta.1",
|
||||
"@0x/contracts-exchange-libs": "^3.1.0-beta.1",
|
||||
"@0x/contracts-exchange": "^2.2.0-beta.1",
|
||||
"@0x/contracts-gen": "^1.1.0-beta.1",
|
||||
"@0x/contracts-test-utils": "^3.2.0-beta.1",
|
||||
"@0x/contracts-utils": "^3.3.0-beta.1",
|
||||
|
@ -5,19 +5,21 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as DeploymentConstants from '../test/generated-artifacts/DeploymentConstants.json';
|
||||
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
|
||||
import * as IERC20BridgeSampler from '../test/generated-artifacts/IERC20BridgeSampler.json';
|
||||
import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json';
|
||||
import * as IExchange from '../test/generated-artifacts/IExchange.json';
|
||||
import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json';
|
||||
import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json';
|
||||
import * as LibERC20Token from '../test/generated-artifacts/LibERC20Token.json';
|
||||
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
|
||||
export const artifacts = {
|
||||
DeploymentConstants: DeploymentConstants as ContractArtifact,
|
||||
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
|
||||
IERC20BridgeSampler: IERC20BridgeSampler as ContractArtifact,
|
||||
IEth2Dai: IEth2Dai as ContractArtifact,
|
||||
IExchange: IExchange as ContractArtifact,
|
||||
IKyberNetwork: IKyberNetwork as ContractArtifact,
|
||||
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
|
||||
LibERC20Token: LibERC20Token as ContractArtifact,
|
||||
TestERC20BridgeSampler: TestERC20BridgeSampler as ContractArtifact,
|
||||
};
|
||||
|
24
contracts/erc20-bridge-sampler/test/erc20-bridge-sampler.ts
Normal file
24
contracts/erc20-bridge-sampler/test/erc20-bridge-sampler.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { blockchainTests, expect, getRandomInteger } from '@0x/contracts-test-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { TestERC20BridgeSamplerContract } from './wrappers';
|
||||
|
||||
blockchainTests('erc20-bridge-sampler', env => {
|
||||
let testContract: TestERC20BridgeSamplerContract;
|
||||
|
||||
before(async () => {
|
||||
testContract = await TestERC20BridgeSamplerContract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestERC20BridgeSampler,
|
||||
env.provider,
|
||||
env.txDefaults,
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
describe('queryOrders()', () => {
|
||||
it('returns the results of `getOrderInfo()` for each order', async () => {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
@ -3,10 +3,11 @@
|
||||
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../test/generated-wrappers/deployment_constants';
|
||||
export * from '../test/generated-wrappers/erc20_bridge_sampler';
|
||||
export * from '../test/generated-wrappers/i_erc20_bridge_sampler';
|
||||
export * from '../test/generated-wrappers/i_eth2_dai';
|
||||
export * from '../test/generated-wrappers/i_exchange';
|
||||
export * from '../test/generated-wrappers/i_kyber_network';
|
||||
export * from '../test/generated-wrappers/i_uniswap_exchange_quotes';
|
||||
export * from '../test/generated-wrappers/lib_erc20_token';
|
||||
export * from '../test/generated-wrappers/test_erc20_bridge_sampler';
|
||||
|
@ -5,13 +5,14 @@
|
||||
"files": [
|
||||
"generated-artifacts/ERC20BridgeSampler.json",
|
||||
"generated-artifacts/IERC20BridgeSampler.json",
|
||||
"test/generated-artifacts/DeploymentConstants.json",
|
||||
"test/generated-artifacts/ERC20BridgeSampler.json",
|
||||
"test/generated-artifacts/IERC20BridgeSampler.json",
|
||||
"test/generated-artifacts/IEth2Dai.json",
|
||||
"test/generated-artifacts/IExchange.json",
|
||||
"test/generated-artifacts/IKyberNetwork.json",
|
||||
"test/generated-artifacts/IUniswapExchangeQuotes.json",
|
||||
"test/generated-artifacts/LibERC20Token.json"
|
||||
"test/generated-artifacts/LibERC20Token.json",
|
||||
"test/generated-artifacts/TestERC20BridgeSampler.json"
|
||||
],
|
||||
"exclude": ["./deploy/solc/solc_bin"]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user