2019-04-05 11:28:08 +00:00
|
|
|
pragma solidity ^0.5.0;
|
|
|
|
|
2019-04-06 12:49:08 +00:00
|
|
|
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
2019-04-05 11:28:08 +00:00
|
|
|
|
2019-04-06 13:23:33 +00:00
|
|
|
interface UniswapFactory {
|
2019-04-05 11:28:08 +00:00
|
|
|
// Get Exchange and Token Info
|
|
|
|
function getExchange(address token) external view returns (address exchange);
|
|
|
|
function getToken(address exchange) external view returns (address token);
|
|
|
|
}
|
|
|
|
|
2019-04-06 13:23:33 +00:00
|
|
|
interface UniswapPool {
|
2019-04-05 11:28:08 +00:00
|
|
|
// Address of ERC20 token sold on this exchange
|
|
|
|
function tokenAddress() external view returns (address token);
|
|
|
|
// Address of Uniswap Factory
|
|
|
|
function factoryAddress() external view returns (address factory);
|
|
|
|
// Provide Liquidity
|
|
|
|
function addLiquidity(uint256 minLiquidity, uint256 maxTokens, uint256 deadline) external payable returns (uint256);
|
|
|
|
// Remove Liquidity
|
|
|
|
function removeLiquidity(
|
|
|
|
uint256 amount,
|
|
|
|
uint256 minEth,
|
|
|
|
uint256 minTokens,
|
|
|
|
uint256 deadline
|
|
|
|
) external returns (uint256, uint256);
|
2019-04-06 09:09:53 +00:00
|
|
|
|
2019-04-05 11:28:08 +00:00
|
|
|
// ERC20 comaptibility for liquidity tokens
|
|
|
|
function name() external returns (bytes32);
|
|
|
|
function symbol() external returns (bytes32);
|
|
|
|
function decimals() external returns (uint256);
|
2019-04-06 11:51:02 +00:00
|
|
|
function totalSupply() external returns (uint256);
|
2019-04-05 11:28:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
contract Helper {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dev get Uniswap Proxy address
|
|
|
|
*/
|
|
|
|
function getAddressUniFactory() public pure returns (address factory) {
|
|
|
|
factory = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get Uniswap's Exchange address from Factory Contract
|
2019-04-06 11:51:02 +00:00
|
|
|
function getAddressPool(address _token) public view returns (address) {
|
2019-04-06 09:09:53 +00:00
|
|
|
return UniswapFactory(getAddressUniFactory()).getExchange(_token);
|
2019-04-05 11:28:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dev get admin address
|
|
|
|
*/
|
|
|
|
function getAddressAdmin() public pure returns (address admin) {
|
|
|
|
admin = 0x7284a8451d9a0e7Dc62B3a71C0593eA2eC5c5638;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dev get fees to trade // 200 => 0.2%
|
|
|
|
*/
|
|
|
|
function getUintFees() public pure returns (uint fees) {
|
|
|
|
fees = 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dev gets ETH & token balance
|
|
|
|
* @param src is the token being sold
|
|
|
|
* @return ethBal - if not erc20, eth balance
|
|
|
|
* @return tknBal - if not eth, erc20 balance
|
|
|
|
*/
|
|
|
|
function getBal(address src, address _owner) public view returns (uint, uint) {
|
2019-04-06 11:51:02 +00:00
|
|
|
uint tknBal = IERC20(src).balanceOf(address(_owner));
|
2019-04-05 11:28:08 +00:00
|
|
|
return (address(_owner).balance, tknBal);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dev setting allowance to kyber for the "user proxy" if required
|
|
|
|
* @param token is the token address
|
|
|
|
*/
|
2019-04-06 13:23:33 +00:00
|
|
|
function setApproval(address token, uint srcAmt, address to) internal {
|
2019-04-06 11:09:34 +00:00
|
|
|
uint tokenAllowance = IERC20(token).allowance(address(this), to);
|
2019-04-05 11:28:08 +00:00
|
|
|
if (srcAmt > tokenAllowance) {
|
2019-04-06 13:23:33 +00:00
|
|
|
IERC20(token).approve(to, 2**255);
|
2019-04-05 11:28:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-04-05 21:44:18 +00:00
|
|
|
|
|
|
|
contract InstaUniswapPool is Helper {
|
|
|
|
|
2019-04-06 11:51:02 +00:00
|
|
|
/**
|
|
|
|
* @title Uniswap's pool basic details
|
|
|
|
* @param token token address to get pool. Eg:- DAI address, MKR address, etc
|
|
|
|
* @param poolAddress Uniswap pool's address
|
|
|
|
* @param name name of pool token
|
|
|
|
* @param symbol symbol of pool token
|
|
|
|
* @param decimals decimals of pool token
|
|
|
|
* @param totalSupply total supply of pool token
|
|
|
|
* @param ethReserve Total ETH balance of uniswap's pool
|
|
|
|
* @param tokenReserve Total Token balance of uniswap's pool
|
|
|
|
*/
|
|
|
|
function poolDetails(
|
|
|
|
address token
|
|
|
|
) public view returns (
|
|
|
|
address poolAddress,
|
|
|
|
bytes32 name,
|
|
|
|
bytes32 symbol,
|
|
|
|
uint256 decimals,
|
|
|
|
uint totalSupply,
|
|
|
|
uint ethReserve,
|
|
|
|
uint tokenReserve
|
2019-04-06 15:36:56 +00:00
|
|
|
)
|
2019-04-06 11:51:02 +00:00
|
|
|
{
|
2019-04-06 15:36:56 +00:00
|
|
|
UniswapPool uniswapExchange = UniswapPool(poolAddress);
|
2019-04-06 11:51:02 +00:00
|
|
|
poolAddress = getAddressPool(token);
|
2019-04-06 15:36:56 +00:00
|
|
|
name = uniswapExchange.name();
|
|
|
|
symbol = uniswapExchange.symbol();
|
|
|
|
decimals = uniswapExchange.decimals();
|
|
|
|
totalSupply = uniswapExchange.totalSupply();
|
2019-04-06 11:51:02 +00:00
|
|
|
(ethReserve, tokenReserve) = getBal(token, poolAddress);
|
|
|
|
}
|
|
|
|
|
2019-04-06 11:21:51 +00:00
|
|
|
/**
|
|
|
|
* @title to add liquidity in pool
|
|
|
|
* @dev payable function token qty to deposit is decided as per the ETH sent by the user
|
|
|
|
* @param token ERC20 address of Uniswap's pool (eg:- DAI address, MKR address, etc)
|
|
|
|
* @param maxDepositedTokens Max token to be deposited
|
|
|
|
*/
|
2019-04-06 09:09:53 +00:00
|
|
|
function addLiquidity(address token, uint maxDepositedTokens) public payable returns (uint256 tokensMinted) {
|
2019-04-06 11:51:02 +00:00
|
|
|
address poolAddr = getAddressPool(token);
|
|
|
|
(uint ethReserve, uint tokenReserve) = getBal(token, poolAddr);
|
|
|
|
uint tokenToDeposit = msg.value * tokenReserve / ethReserve + 1;
|
2019-04-05 21:44:18 +00:00
|
|
|
require(tokenToDeposit < maxDepositedTokens, "Token to deposit is greater than Max token to Deposit");
|
2019-04-06 10:44:15 +00:00
|
|
|
IERC20(token).transferFrom(msg.sender, address(this), tokenToDeposit);
|
2019-04-06 13:23:33 +00:00
|
|
|
setApproval(token, tokenToDeposit, poolAddr);
|
2019-04-06 11:51:02 +00:00
|
|
|
tokensMinted = UniswapPool(poolAddr).addLiquidity.value(msg.value)(
|
2019-04-06 09:09:53 +00:00
|
|
|
uint(0),
|
|
|
|
tokenToDeposit,
|
|
|
|
uint(1899063809) // 6th March 2030 GMT // no logic
|
|
|
|
);
|
2019-04-05 21:44:18 +00:00
|
|
|
}
|
|
|
|
|
2019-04-06 11:21:51 +00:00
|
|
|
/**
|
|
|
|
* @title to remove liquidity from pool
|
|
|
|
* @dev ETH and token quantity is decided as per the exchange token qty to burn
|
|
|
|
* @param token ERC20 address of Uniswap's pool (eg:- DAI address, MKR address, etc)
|
|
|
|
* @param amount Uniswap pool's ERC20 token QTY to burn
|
|
|
|
* @param minEth Min ETH user to be returned
|
|
|
|
* @param minTokens Min Tokens to be returned
|
|
|
|
*/
|
2019-04-06 11:09:34 +00:00
|
|
|
function removeLiquidity(
|
|
|
|
address token,
|
|
|
|
uint amount,
|
|
|
|
uint minEth,
|
|
|
|
uint minTokens
|
2019-04-06 11:21:51 +00:00
|
|
|
) public returns (uint ethReturned, uint tokenReturned)
|
2019-04-06 11:09:34 +00:00
|
|
|
{
|
2019-04-06 11:51:02 +00:00
|
|
|
address poolAddr = getAddressPool(token);
|
2019-04-06 13:23:33 +00:00
|
|
|
setApproval(poolAddr, amount, poolAddr);
|
2019-04-06 11:51:02 +00:00
|
|
|
(ethReturned, tokenReturned) = UniswapPool(poolAddr).removeLiquidity(
|
2019-04-06 11:09:34 +00:00
|
|
|
amount,
|
|
|
|
minEth,
|
|
|
|
minTokens,
|
|
|
|
uint(1899063809) // 6th March 2030 GMT // no logic
|
|
|
|
);
|
|
|
|
address(msg.sender).transfer(ethReturned);
|
|
|
|
IERC20(token).transfer(msg.sender, tokenReturned);
|
|
|
|
}
|
2019-04-06 10:44:15 +00:00
|
|
|
|
2019-04-05 21:44:18 +00:00
|
|
|
}
|