-
Notifications
You must be signed in to change notification settings - Fork 0
/
Belotto_Crowdsale.sol
332 lines (287 loc) · 12.1 KB
/
Belotto_Crowdsale.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
pragma solidity ^0.4.23;
// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
library SafeMath {
function add(uint a, uint b) internal pure returns (uint c) {
c = a + b;
require(c >= a);
}
function sub(uint a, uint b) internal pure returns (uint c) {
require(b <= a);
c = a - b;
}
function mul(uint a, uint b) internal pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
}
function div(uint a, uint b) internal pure returns (uint c) {
require(b > 0);
c = a / b;
}
}
// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
address public owner;
address public newOwner;
event OwnershipTransferred(address indexed _from, address indexed _to);
modifier onlyOwner {
require(msg.sender == owner, "ONLY OWNER IS ALLOWED");
_;
}
function transferOwnership(address _newOwner) public onlyOwner {
newOwner = _newOwner;
}
function acceptOwnership() public {
require(msg.sender == newOwner);
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
newOwner = address(0);
}
}
contract IBelottoToken{
function transfer(address to, uint tokens) public returns (bool success);
function burn(uint256 _value) public;
function balanceOf(address tokenOwner) public constant returns (uint balance);
}
/**
* @title BelottoCrowdsale
* @dev BelottoCrowdsale accepting contributions only within a time frame.
*/
contract BelottoCrowdsale is Owned {
using SafeMath for uint256;
uint256 public presaleopeningTime;
uint256 public presaleclosingTime;
uint256 public saleopeningTime;
uint256 public saleclosingTime;
uint256 public secondsaleopeningTime;
uint256 public secondsaleclosingTime;
address public reserverWallet; // Address where reserve tokens will be sent
address public bountyWallet; // Address where bounty tokens will be sent
address public teamsWallet; // Address where team's tokens will be sent
address public fundsWallet; // Address where funds are collected
uint256 public fundsRaised; // Amount of total fundsRaised
uint256 public preSaleTokens;
uint256 public saleTokens;
uint256 public teamAdvTokens;
uint256 public reserveTokens;
uint256 public bountyTokens;
uint256 public hardCap;
uint256 public minTxSize;
uint256 public maxTxSize;
bool public presaleOpen;
bool public firstsaleOpen;
bool public secondsaleOpen;
mapping(address => uint) preSaleFunds;
mapping(address => uint) firstSaleFunds;
mapping(address => uint) secondSaleFunds;
struct Funds {
address spender;
uint256 amount;
uint256 time;
}
Funds[] preSaleFundsArray;
Funds[] firstSaleFundsArray;
Funds[] secondSaleFundsArray;
IBelottoToken public token;
event Burn(address indexed burner, uint256 value);
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
/** @dev Reverts if not in crowdsale time range. */
modifier onlyWhilePreSaleOpen {
require(now >= presaleopeningTime && now <= presaleclosingTime, "Pre Sale Close");
_;
}
modifier onlyWhileFirstSaleOpen {
require(now >= saleopeningTime && now <= saleclosingTime, "First Sale Close");
_;
}
modifier onlyWhileSecondSaleOpen {
require(now >= secondsaleopeningTime && now <= secondsaleclosingTime, "Second Sale Close");
_;
}
function totalRemainingTokens() public view returns(uint256 remainingTokens){
return token.balanceOf(this);
}
function BelottoCrowdsale(uint256 _preST, uint256 _saleT, uint256 _teamAdvT, uint256 _reserveT, uint256 _bountyT, address _reserverWallet,
address _bountyWallet, address _teamsWallet, address _fundsWallet, address _tokenContractAdd, address _owner)
public {
_setWallets(_reserverWallet,_bountyWallet,_teamsWallet,_fundsWallet);
_setMoreDetails(_preST,_saleT,_teamAdvT,_reserveT,_bountyT,_owner);
_setTimes();
// takes an address of the existing token contract as parameter
token = IBelottoToken(_tokenContractAdd);
}
function _setTimes() internal{
presaleopeningTime = 1524873600; // 28th April 2018 00:00:00 GMT
presaleclosingTime = 1527379199; // 26th May 2018 23:59:59 GMT
saleopeningTime = 1527724800; // 31st May 2018 00:00:00 GMT
saleclosingTime = 1532908799; // 29th July 2018 23:59:59 GMT
secondsaleopeningTime = 1532908800; // 30th July 2018 00:00:00 GMT
secondsaleclosingTime = 1535673599; // 30th August 2018 23:59:59 GMT
}
function _setWallets(address _reserverWallet, address _bountyWallet, address _teamsWallet, address _fundsWallet) internal{
reserverWallet = _reserverWallet;
bountyWallet = _bountyWallet;
teamsWallet = _teamsWallet;
fundsWallet = _fundsWallet;
}
function _setMoreDetails(uint256 _preST, uint256 _saleT, uint256 _teamAdvT, uint256 _reserveT, uint256 _bountyT, address _owner) internal{
preSaleTokens = _preST * 10**uint(18);
saleTokens = _saleT * 10**uint(18);
teamAdvTokens = _teamAdvT * 10**uint(18);
reserveTokens = _reserveT * 10**uint(18);
bountyTokens = _bountyT * 10**uint(18);
hardCap = 16000 * 10**(uint(18)); //in start only, it'll be set by Owner
minTxSize = 100000000000000000; // in wei's. (0,1 ETH)
maxTxSize = 200000000000000000000; // in wei's. (200 ETH)
owner = _owner;
}
function TokenAllocate(address _wallet,uint256 _amount) internal returns (bool success) {
uint256 tokenAmount = _amount;
token.transfer(_wallet,tokenAmount);
return true;
}
function startSecondSale() public onlyOwner{
presaleOpen = false;
firstsaleOpen = false;
secondsaleOpen = true;
}
function stopSecondSale() public onlyOwner{
presaleOpen = false;
firstsaleOpen = false;
secondsaleOpen = false;
if(teamAdvTokens >= 0 && bountyTokens >=0){
TokenAllocate(teamsWallet,teamAdvTokens);
teamAdvTokens = 0;
TokenAllocate(bountyWallet,bountyTokens);
bountyTokens = 0;
}
}
function _checkOpenings(uint256 _weiAmount) internal{
if((fundsRaised + _weiAmount >= hardCap)){
presaleOpen = false;
firstsaleOpen = false;
secondsaleOpen = true;
}
else if(secondsaleOpen){
presaleOpen = false;
firstsaleOpen = false;
secondsaleOpen = true;
}
else if(now >= presaleopeningTime && now <= presaleclosingTime){
presaleOpen = true;
firstsaleOpen = false;
secondsaleOpen = false;
if(reserveTokens >= 0){
if(TokenAllocate(reserverWallet,reserveTokens)){
reserveTokens = 0;
}
}
}
else if(now >= saleopeningTime && now <= saleclosingTime){
presaleOpen = false;
firstsaleOpen = true;
secondsaleOpen = false;
}
else if(now >= secondsaleopeningTime && now <= secondsaleclosingTime){
presaleOpen = false;
firstsaleOpen = false;
secondsaleOpen = true;
}
else{
presaleOpen = false;
firstsaleOpen = false;
secondsaleOpen = false;
if(teamAdvTokens >= 0 && bountyTokens >=0){
TokenAllocate(teamsWallet,teamAdvTokens);
teamAdvTokens = 0;
TokenAllocate(bountyWallet,bountyTokens);
bountyTokens = 0;
}
}
}
function () external payable {
buyTokens(msg.sender);
}
function buyTokens(address _beneficiary) public payable {
uint256 ethers = msg.value;
_preValidatePurchase(_beneficiary, ethers);
_checkOpenings(ethers);
_setFunds(_beneficiary,ethers);
// update state of wei's raised during complete ICO
fundsRaised = fundsRaised.add(ethers);
//sjfhj
_forwardFunds(_beneficiary);
}
function _setFunds(address _beneficiary, uint256 _ethers) internal{
if(presaleOpen){
preSaleFundsArray.push(Funds(_beneficiary,_ethers, now));
}
else if(firstsaleOpen){
firstSaleFundsArray.push(Funds(_beneficiary,_ethers, now));
}
else if(secondsaleOpen){
secondSaleFundsArray.push(Funds(_beneficiary,_ethers, now));
}
}
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal{
require(_beneficiary != address(0), "WRONG Address");
require(_weiAmount != 0, "Insufficient funds");
require(_weiAmount >= minTxSize && _weiAmount <= maxTxSize ,"FUNDS should be MIN 0,1 ETH and Max 200 ETH");
}
function TotalSpenders() public view returns (uint256 preSaleSpenders,uint256 firstSaleSpenders,uint256 secondSaleSpenders){
return ((preSaleFundsArray.length),(firstSaleFundsArray.length),(secondSaleFundsArray.length));
}
function _forwardFunds(address _beneficiary) internal {
fundsWallet.transfer(msg.value);
}
function preSaleDelivery(address _beneficiary, uint256 _tokenAmount) public onlyOwner{
_checkOpenings(0);
require(!presaleOpen, "Pre-Sale is NOT CLOSE ");
require(preSaleTokens >= _tokenAmount,"NO Pre-SALE Tokens Available");
token.transfer(_beneficiary,_tokenAmount);
preSaleTokens = preSaleTokens.sub(_tokenAmount);
}
function firstSaleDelivery(address _beneficiary, uint256 _tokenAmount) public onlyOwner{
require(!presaleOpen && !firstsaleOpen, "First Sale is NOT CLOSE");
if(saleTokens <= _tokenAmount && preSaleTokens >= _tokenAmount){
saleTokens = saleTokens.add(_tokenAmount);
preSaleTokens = preSaleTokens.sub(_tokenAmount);
}
token.transfer(_beneficiary,_tokenAmount);
saleTokens = saleTokens.sub(_tokenAmount);
}
function secondSaleDelivery(address _beneficiary, uint256 _tokenAmount) public onlyOwner{
require(!presaleOpen && !firstsaleOpen && !secondsaleOpen, "Second Sale is NOT CLOSE");
require(saleTokens >= _tokenAmount,"NO Sale Tokens Available");
token.transfer(_beneficiary,_tokenAmount);
saleTokens = saleTokens.sub(_tokenAmount);
}
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function burnTokens(uint256 _value) public onlyOwner {
token.burn(_value);
}
function preSaleSpenderTxDetails(uint _index) public view returns(address spender, uint256 amount, uint256 time){
return (preSaleFundsArray[_index].spender,preSaleFundsArray[_index].amount,preSaleFundsArray[_index].time);
}
function firstSaleSpenderTxDetails(uint _index) public view returns(address spender, uint256 amount, uint256 time){
return (firstSaleFundsArray[_index].spender,firstSaleFundsArray[_index].amount,firstSaleFundsArray[_index].time);
}
function secSaleSpenderTxDetails(uint _index) public view returns(address spender, uint256 amount, uint256 time){
return (secondSaleFundsArray[_index].spender,secondSaleFundsArray[_index].amount,secondSaleFundsArray[_index].time);
}
function transferRemainingTokens(address _to,uint256 _tokens) public onlyOwner {
require(!presaleOpen && !firstsaleOpen && !secondsaleOpen);
uint myBalance = token.balanceOf(this);
require(myBalance >= _tokens);
token.transfer(_to,_tokens);
}
function updateHardCap(uint256 _hardCap)public onlyOwner {
hardCap = _hardCap * 10**uint(18);
}
}