mirror of
https://github.com/Instadapp/smart-contract.git
synced 2024-07-29 22:08:07 +00:00
236 lines
7.6 KiB
Solidity
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 {}
|
|
|
|
} |