diff --git a/contracts/sol6/bridgeReserve/CoFix/KyberCofixReserve.sol b/contracts/sol6/bridgeReserve/CoFix/KyberCofixReserve.sol new file mode 100644 index 000000000..5d47c4d06 --- /dev/null +++ b/contracts/sol6/bridgeReserve/CoFix/KyberCofixReserve.sol @@ -0,0 +1,74 @@ +pragma solidity 0.6.6; + +import "../../IKyberReserve.sol"; +import "../../IERC20.sol"; +import "../../utils/Withdrawable3.sol"; +import "../../utils/Utils5.sol"; +import "../../utils/zeppelin/SafeERC20.sol"; +import "./mock/ICoFiXRouter.sol"; +import "./mock/ICoFiXFactory.sol"; +import "./mock/INest_3_OfferPrice.sol"; + +contract KyberCofixReserve is IKyberReserve, Withdrawable3, Utils5 { + using SafeERC20 for IERC20; + + ICoFiXRouter iCoFiXRouter; + ICoFiXFactory iCoFixFactory; + INest_3_OfferPrice iNest_3_OfferPrice; + address NESTOracle = 0x7722891Ee45aD38AE05bDA8349bA4CF23cFd270F; + address cofixFactory = 0xd5a19e1adb5592921dcc42e48623d75c4c91e405; + + constructor( + ICoFiXRouter _iCoFiXRouter, + address _weth, + address _admin, + address _kyberNetwork + ) public Withdrawable3(_admin) { + require(address(_iCoFiXRouter) != address(0), "_iCoFiXRouter 0"); + require(_weth != address(0), "weth 0"); + require(_kyberNetwork != address(0), "kyberNetwork 0"); + + iCoFiXRouter = _iCoFiXRouter; + iCoFixFactory = iCoFixFactory(cofixFactory); + iNest_3_OfferPrice = INest_3_OfferPrice(NESTOracle); + weth = _weth; + kyberNetwork = _kyberNetwork; + } + + //TODO complete + function trade( + IERC20 srcToken, + uint256 srcAmount, + IERC20 destToken, + address payable destAddress, + uint256 conversionRate, + bool validate + ) public payable returns (bool) { + (uint256 ethAmountSrc, uint256 erc20AmountSrc) = iNest_3_OfferPrice.checkPriceForBlock(address(src), blockNumber); + uint amountMinEth = (srcAmount / erc20AmountSrc) * ethAmountSrc; + //TODO what if one of the tokens is actually eth? + iCoFiXRouter.swapExactTokensForTokens( + srcToken, + destToken, + srcAmount, + amountMinEth, + destAddress, + block.now + 100000 //TODO how should the deadline be set? + ); + return true; + } + + //TODO complete + function getConversionRate( + IERC20 src, + IERC20 dest, + uint256 srcQty, + uint256 blockNumber + ) public view returns (uint256) { + (uint256 ethAmountSrc, uint256 erc20AmountSrc) = iNest_3_OfferPrice.checkPriceForBlock(address(src), blockNumber); + (uint256 ethAmountDest, uint256 erc20AmountDest) = iNest_3_OfferPrice.checkPriceForBlock(address(dest), blockNumber); + return srcQty * (ethAmountSrc / ethAmountDest); + } + + +} diff --git a/contracts/sol6/bridgeReserve/CoFix/mock/ICoFiXFactory.sol b/contracts/sol6/bridgeReserve/CoFix/mock/ICoFiXFactory.sol new file mode 100644 index 000000000..3fabe24ef --- /dev/null +++ b/contracts/sol6/bridgeReserve/CoFix/mock/ICoFiXFactory.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity ^0.6.6; + +interface ICoFiXFactory { + // All pairs: {ETH <-> ERC20 Token} + event PairCreated(address indexed token, address pair, uint256); + + /// @dev Create a new token pair for trading + /// @param token the address of token to trade + /// @return pair the address of new token pair + function createPair( + address token + ) + external + returns (address pair); + + function getPair(address token) external view returns (address pair); + function allPairs(uint256) external view returns (address pair); + function allPairsLength() external view returns (uint256); + + function setGovernance(address _new) external; + function setController(address _new) external; + function setFeeReceiver(address _new) external; + function setVaultForLP(address _new) external; + function getController() external view returns (address controller); + function getFeeReceiver() external view returns (address feeReceiver); + function getVaultForLP() external view returns (address vaultForLP); +} \ No newline at end of file diff --git a/contracts/sol6/bridgeReserve/CoFix/mock/ICoFiXRouter.sol b/contracts/sol6/bridgeReserve/CoFix/mock/ICoFiXRouter.sol new file mode 100644 index 000000000..1c1f537f6 --- /dev/null +++ b/contracts/sol6/bridgeReserve/CoFix/mock/ICoFiXRouter.sol @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity 0.6.12; + +interface ICoFiXRouter { + function factory() external pure returns (address); + function WETH() external pure returns (address); + + // All pairs: {ETH <-> ERC20 Token} + + /// @dev Maker add liquidity to pool, get pool token (mint XToken to maker) (notice: msg.value = amountETH + oracle fee) + /// @param token The address of ERC20 Token + /// @param amountETH The amount of ETH added to pool + /// @param amountToken The amount of Token added to pool + /// @param liquidityMin The minimum liquidity maker wanted + /// @param to The target address receiving the liquidity pool (XToken) + /// @param deadline The dealine of this request + /// @return liquidity The real liquidity or XToken minted from pool + function addLiquidity( + address token, + uint amountETH, + uint amountToken, + uint liquidityMin, + address to, + uint deadline + ) external payable returns (uint liquidity); + + /// @dev Maker add liquidity to pool, get pool token (mint XToken) and stake automatically (notice: msg.value = amountETH + oracle fee) + /// @param token The address of ERC20 Token + /// @param amountETH The amount of ETH added to pool + /// @param amountToken The amount of Token added to pool + /// @param liquidityMin The minimum liquidity maker wanted + /// @param to The target address receiving the liquidity pool (XToken) + /// @param deadline The dealine of this request + /// @return liquidity The real liquidity or XToken minted from pool + function addLiquidityAndStake( + address token, + uint amountETH, + uint amountToken, + uint liquidityMin, + address to, + uint deadline + ) external payable returns (uint liquidity); + + /// @dev Maker remove liquidity from pool to get ERC20 Token back (maker burn XToken) (notice: msg.value = oracle fee) + /// @param token The address of ERC20 Token + /// @param liquidity The amount of liquidity (XToken) sent to pool, or the liquidity to remove + /// @param amountTokenMin The minimum amount of Token wanted to get from pool + /// @param to The target address receiving the Token + /// @param deadline The dealine of this request + /// @return amountToken The real amount of Token transferred from the pool + function removeLiquidityGetToken( + address token, + uint liquidity, + uint amountTokenMin, + address to, + uint deadline + ) external payable returns (uint amountToken); + + /// @dev Maker remove liquidity from pool to get ETH back (maker burn XToken) (notice: msg.value = oracle fee) + /// @param token The address of ERC20 Token + /// @param liquidity The amount of liquidity (XToken) sent to pool, or the liquidity to remove + /// @param amountETHMin The minimum amount of ETH wanted to get from pool + /// @param to The target address receiving the ETH + /// @param deadline The dealine of this request + /// @return amountETH The real amount of ETH transferred from the pool + function removeLiquidityGetETH( + address token, + uint liquidity, + uint amountETHMin, + address to, + uint deadline + ) external payable returns (uint amountETH); + + /// @dev Trader swap exact amount of ETH for ERC20 Tokens (notice: msg.value = amountIn + oracle fee) + /// @param token The address of ERC20 Token + /// @param amountIn The exact amount of ETH a trader want to swap into pool + /// @param amountOutMin The minimum amount of Token a trader want to swap out of pool + /// @param to The target address receiving the Token + /// @param deadline The dealine of this request + /// @return _amountIn The real amount of ETH transferred into pool + /// @return _amountOut The real amount of Token transferred out of pool + function swapExactETHForTokens( + address token, + uint amountIn, + uint amountOutMin, + address to, + uint deadline + ) external payable returns (uint _amountIn, uint _amountOut); + + /// @dev Trader swap exact amount of ERC20 Tokens for ETH (notice: msg.value = oracle fee) + /// @param token The address of ERC20 Token + /// @param amountIn The exact amount of Token a trader want to swap into pool + /// @param amountOutMin The mininum amount of ETH a trader want to swap out of pool + /// @param to The target address receiving the ETH + /// @param deadline The dealine of this request + /// @return _amountIn The real amount of Token transferred into pool + /// @return _amountOut The real amount of ETH transferred out of pool + function swapExactTokensForETH( + address token, + uint amountIn, + uint amountOutMin, + address to, + uint deadline + ) external payable returns (uint _amountIn, uint _amountOut); + + /// @dev Trader swap exact amount of ERC20 Tokens for other ERC20 Tokens (notice: msg.value = oracle fee) + /// @param tokenIn The address of ERC20 Token a trader want to swap into pool + /// @param tokenOut The address of ERC20 Token a trader want to swap out of pool + /// @param amountIn The exact amount of Token a trader want to swap into pool + /// @param amountOutMin The mininum amount of ETH a trader want to swap out of pool + /// @param to The target address receiving the Token + /// @param deadline The dealine of this request + /// @return _amountIn The real amount of Token transferred into pool + /// @return _amountOut The real amount of Token transferred out of pool + function swapExactTokensForTokens( + address tokenIn, + address tokenOut, + uint amountIn, + uint amountOutMin, + address to, + uint deadline + ) external payable returns (uint _amountIn, uint _amountOut); + + /// @dev Trader swap ETH for exact amount of ERC20 Tokens (notice: msg.value = amountInMax + oracle fee) + /// @param token The address of ERC20 Token + /// @param amountInMax The max amount of ETH a trader want to swap into pool + /// @param amountOutExact The exact amount of Token a trader want to swap out of pool + /// @param to The target address receiving the Token + /// @param deadline The dealine of this request + /// @return _amountIn The real amount of ETH transferred into pool + /// @return _amountOut The real amount of Token transferred out of pool + function swapETHForExactTokens( + address token, + uint amountInMax, + uint amountOutExact, + address to, + uint deadline + ) external payable returns (uint _amountIn, uint _amountOut); + + /// @dev Trader swap ERC20 Tokens for exact amount of ETH (notice: msg.value = oracle fee) + /// @param token The address of ERC20 Token + /// @param amountInMax The max amount of Token a trader want to swap into pool + /// @param amountOutExact The exact amount of ETH a trader want to swap out of pool + /// @param to The target address receiving the ETH + /// @param deadline The dealine of this request + /// @return _amountIn The real amount of Token transferred into pool + /// @return _amountOut The real amount of ETH transferred out of pool + function swapTokensForExactETH( + address token, + uint amountInMax, + uint amountOutExact, + address to, + uint deadline + ) external payable returns (uint _amountIn, uint _amountOut); +} diff --git a/contracts/sol6/bridgeReserve/CoFix/mock/INest_3_OfferPrice.sol b/contracts/sol6/bridgeReserve/CoFix/mock/INest_3_OfferPrice.sol new file mode 100644 index 000000000..3d07aa2e1 --- /dev/null +++ b/contracts/sol6/bridgeReserve/CoFix/mock/INest_3_OfferPrice.sol @@ -0,0 +1,6 @@ +pragma solidity 0.6.0; + +interface INest_3_OfferPrice { + // Check block price - user account only + function checkPriceForBlock(address tokenAddress, uint256 blockNum) external view returns (uint256 ethAmount, uint256 erc20Amount); +} \ No newline at end of file