-
Notifications
You must be signed in to change notification settings - Fork 15
/
PresaleLockForwarder.sol
128 lines (105 loc) · 5.81 KB
/
PresaleLockForwarder.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// SPDX-License-Identifier: UNLICENSED
// @Credits Unicrypt Network 2021
/**
This contract creates the lock on behalf of each presale. This contract will be whitelisted to bypass the flat rate
ETH fee. Please do not use the below locking code in your own contracts as the lock will fail without the ETH fee
*/
pragma solidity 0.6.12;
import "./Ownable.sol";
import "./TransferHelper.sol";
import "./IERC20.sol";
interface IPresaleFactory {
function registerPresale (address _presaleAddress) external;
function presaleIsRegistered(address _presaleAddress) external view returns (bool);
}
interface IUniswapV2Locker {
function lockLPToken (address _lpToken, uint256 _amount, uint256 _unlock_date, address payable _referral, bool _fee_in_eth, address payable _withdrawer) external payable;
}
interface IUniswapV2Factory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function price0CumulativeLast() external view returns (uint);
function price1CumulativeLast() external view returns (uint);
function kLast() external view returns (uint);
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
}
contract PresaleLockForwarder is Ownable {
IPresaleFactory public PRESALE_FACTORY;
IUniswapV2Locker public OCTOFI_LOCKER;
IUniswapV2Factory public UNI_FACTORY;
constructor() public {
PRESALE_FACTORY = IPresaleFactory(0xF7237475185053eFE89A12E5dEeA6c00ABE2857e);
OCTOFI_LOCKER = IUniswapV2Locker(0xf40A4A2300152921E16dE1EBe4ec72B244375cF6);
UNI_FACTORY = IUniswapV2Factory(0x0044583d20C5C7E80c2Ac84A6D2E9Ee3521F7aA2);
}
/**
Send in _token0 as the PRESALE token, _token1 as the BASE token (usually WETH) for the check to work. As anyone can create a pair,
and send WETH to it while a presale is running, but no one should have access to the presale token. If they do and they send it to
the pair, scewing the initial liquidity, this function will return true
*/
function uniswapPairIsInitialised (address _token0, address _token1) public view returns (bool) {
address pairAddress = UNI_FACTORY.getPair(_token0, _token1);
if (pairAddress == address(0)) {
return false;
}
uint256 balance = IERC20(_token0).balanceOf(pairAddress);
if (balance > 0) {
return true;
}
return false;
}
function lockLiquidity (IERC20 _baseToken, IERC20 _saleToken, uint256 _baseAmount, uint256 _saleAmount, uint256 _unlock_date, address payable _withdrawer) external {
require(PRESALE_FACTORY.presaleIsRegistered(msg.sender), 'PRESALE NOT REGISTERED');
address pair = UNI_FACTORY.getPair(address(_baseToken), address(_saleToken));
if (pair == address(0)) {
UNI_FACTORY.createPair(address(_baseToken), address(_saleToken));
pair = UNI_FACTORY.getPair(address(_baseToken), address(_saleToken));
}
TransferHelper.safeTransferFrom(address(_baseToken), msg.sender, address(pair), _baseAmount);
TransferHelper.safeTransferFrom(address(_saleToken), msg.sender, address(pair), _saleAmount);
IUniswapV2Pair(pair).mint(address(this));
uint256 totalLPTokensMinted = IUniswapV2Pair(pair).balanceOf(address(this));
require(totalLPTokensMinted != 0 , "LP creation failed");
TransferHelper.safeApprove(pair, address(OCTOFI_LOCKER), totalLPTokensMinted);
uint256 unlock_date = _unlock_date > 9999999999 ? 9999999999 : _unlock_date;
OCTOFI_LOCKER.lockLPToken(pair, totalLPTokensMinted, unlock_date, address(0), true, _withdrawer);
}
}