smart-contract/contracts/ProxyLogics/InstaUniswapPool.sol
2019-05-01 15:37:18 +05:30

236 lines
7.6 KiB
Solidity

pragma solidity ^0.5.0;
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
}
interface UniswapFactory {
// Get Exchange and Token Info
function getExchange(address token) external view returns (address exchange);
}
interface UniswapPool {
// 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);
// ERC20 comaptibility for liquidity tokens
function totalSupply() external view returns (uint);
}
contract Helper {
/**
* @dev get Uniswap Proxy address
*/
function getAddressUniFactory() public pure returns (address factory) {
factory = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
// factory = 0xf5D915570BC477f9B8D6C0E980aA81757A3AaC36; // Rinkeby
}
// Get Uniswap's Exchange address from Factory Contract
function getAddressPool(address _token) public view returns (address) {
return UniswapFactory(getAddressUniFactory()).getExchange(_token);
}
/**
* @dev get admin address
*/
function getAddressAdmin() public pure returns (address admin) {
admin = 0x7284a8451d9a0e7Dc62B3a71C0593eA2eC5c5638;
}
/**
* @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) internal view returns (uint, uint) {
uint tknBal = IERC20(src).balanceOf(address(_owner));
return (address(_owner).balance, tknBal);
}
/**
* @dev setting allowance to kyber for the "user proxy" if required
* @param token is the token address
*/
function setApproval(address token, uint srcAmt, address to) internal {
IERC20 erc20Contract = IERC20(token);
uint tokenAllowance = erc20Contract.allowance(address(this), to);
if (srcAmt > tokenAllowance) {
erc20Contract.approve(to, 2**255);
}
}
}
contract Pool is Helper {
event LogAddLiquidity(
address token,
uint tokenAmt,
uint ethAmt,
uint poolTokenMinted,
address beneficiary
);
event LogRemoveLiquidity(
address token,
uint tokenReturned,
uint ethReturned,
uint poolTokenBurned,
address beneficiary
);
event LogShutPool(
address token,
uint tokenReturned,
uint ethReturned,
uint poolTokenBurned,
address beneficiary
);
/**
* @dev 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 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,
uint totalSupply,
uint ethReserve,
uint tokenReserve
)
{
poolAddress = getAddressPool(token);
totalSupply = IERC20(poolAddress).totalSupply();
(ethReserve, tokenReserve) = getBal(token, poolAddress);
}
/**
* @dev to add liquidity in pool. 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
*/
function addLiquidity(address token, uint maxDepositedTokens) public payable returns (uint256 tokensMinted) {
address poolAddr = getAddressPool(token);
(uint ethReserve, uint tokenReserve) = getBal(token, poolAddr);
uint tokenToDeposit = msg.value * tokenReserve / ethReserve + 1;
require(tokenToDeposit < maxDepositedTokens, "Token to deposit is greater than Max token to Deposit");
IERC20(token).transferFrom(msg.sender, address(this), tokenToDeposit);
setApproval(token, tokenToDeposit, poolAddr);
tokensMinted = UniswapPool(poolAddr).addLiquidity.value(msg.value)(
uint(1),
tokenToDeposit,
uint(1899063809) // 6th March 2030 GMT // no logic
);
emit LogAddLiquidity(
token,
tokenToDeposit,
msg.value,
tokensMinted,
msg.sender
);
}
/**
* @dev to remove liquidity from pool. 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
*/
function removeLiquidity(
address token,
uint amount,
uint minEth,
uint minTokens
) public returns (uint ethReturned, uint tokenReturned)
{
address poolAddr = getAddressPool(token);
setApproval(poolAddr, amount, poolAddr);
(ethReturned, tokenReturned) = UniswapPool(poolAddr).removeLiquidity(
amount,
minEth,
minTokens,
uint(1899063809) // 6th March 2030 GMT // no logic
);
address(msg.sender).transfer(ethReturned);
IERC20(token).transfer(msg.sender, tokenReturned);
emit LogRemoveLiquidity(
token,
tokenReturned,
ethReturned,
amount,
msg.sender
);
}
/**
* @dev to remove all of the user's liquidity from pool. 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)
*/
function shut(address token) public returns (uint ethReturned, uint tokenReturned) {
address poolAddr = getAddressPool(token);
uint userPoolBal = IERC20(poolAddr).balanceOf(address(this));
setApproval(poolAddr, userPoolBal, poolAddr);
(ethReturned, tokenReturned) = UniswapPool(poolAddr).removeLiquidity(
userPoolBal,
uint(1),
uint(1),
uint(1899063809) // 6th March 2030 GMT // no logic
);
address(msg.sender).transfer(ethReturned);
IERC20(token).transfer(msg.sender, tokenReturned);
emit LogShutPool(
token,
tokenReturned,
ethReturned,
userPoolBal,
msg.sender
);
}
}
contract InstaUniswapPool is Pool {
uint public version;
/**
* @dev setting up variables on deployment
* 1...2...3 versioning in each subsequent deployments
*/
constructor(uint _version) public {
version = _version;
}
function() external payable {}
}