-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSLPRcoinCrowdSale.sol
306 lines (251 loc) · 12.3 KB
/
SLPRcoinCrowdSale.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
pragma solidity ^0.5.0;
import "./SLPRcoin.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Mintable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/TokenTimelock.sol";
import "@openzeppelin/contracts/crowdsale/Crowdsale.sol";
import "@openzeppelin/contracts/crowdsale/emission/MintedCrowdsale.sol";
import "@openzeppelin/contracts/crowdsale/validation/CappedCrowdsale.sol";
import "@openzeppelin/contracts/crowdsale/validation/TimedCrowdsale.sol";
import "@openzeppelin/contracts/crowdsale/validation/WhitelistCrowdsale.sol";
import "@openzeppelin/contracts/crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol";
/** The SLPRcoinCrowdSale contract inherits standards and properties from the following Crowdsale contracts:
*
* CROWDSALE: Base architecture for crowdsales. Sets up a wallet to collect funds. Framework to send Ether to the Smart Contract &
* compute the amount of Tokens disbursed based on the rate.
*
* MINTEDCROWDSALE: The contract will mint Tokens anytime they are purchased, instead of having a preset total supply.
* The total amount of tokens in distribution is determined by how many are actually sold.
*
* TIMEDCROWDSALE: Sets parameters to start (openingTime) and end (closingTime) the Crowdsale.
*
* CAPPEDCROWDSALE: Sets the max amount of runds it can raise in the Crowdsale.
*
* WHITELISTCROWDSALE: Sets parameters to fullfill KYC requirements. Match contributions in the Crowdsale to real people. Investors
* must be WhiteListed before they can purchase Tokens.
*
* STAGED CROWDSALE: Creates 2 stages (pre-sale and public sale) to set rates where investors can receive more Tokens in the pre-sale
* vs the public sale. In pre-sale, funds go to the wallet, not to the refund escrow vault.
*
* REFUNDABLECROWDSALE: Sets a minimum goal of funds to raise in the Crowdsale. If goal isn't reached, it will refund investors.
*
* DISTRIBUTION & VESTING: Set amount of Tokens to distribute to Founders, Company, and Public.
*/
contract SLPRcoinCrowdSale is Crowdsale, MintedCrowdsale, CappedCrowdsale, TimedCrowdsale, WhitelistCrowdsale, RefundablePostDeliveryCrowdsale {
//address token_sale_address;
//address owner = msg.sender;
//address token_sale_address;
// Track investor contributions. Set Minimum and Maximum contributions.
uint256 public investorMinCap = 2000000000000000; // 0.002 ether
uint256 public investorHardCap = 50000000000000000000; // 50 ether
// Create a mapping to hold record of investor contributions.
mapping(address => uint256) public contributions;
// Set Crowdsale Stages to manage presale and public token rates
enum CrowdsaleStage { PreICO, ICO }
// Set default stage to presale stage
CrowdsaleStage public stage = CrowdsaleStage.PreICO;
// Set token Distribution percentages for public sale and Token Resereves
// (Public: 70%, Founders, Foundation, Partners: 10% each)
uint256 public tokenSalePercentage = 70;
uint256 public foundersPercentage = 10;
uint256 public foundationPercentage = 10;
uint256 public partnersPercentage = 10;
uint256 private _weiRaised = 0;
// Create addresses for Token Reserve funds
address public foundersFund;
address public foundationFund;
address public partnersFund;
// Create token Time Lock addreses to set token holding time frame
uint256 public releaseTime;
address public foundersTimelock;
address public foundationTimelock;
address public partnersTimelock;
// Create the contract's constructor to pass parameters from inherited contracts
// Crowdsale(rate, wallet, token), CappedCrowdsale(cap), TimedCrowdsale(openingTime, closingTime), RefundableCrowdsale(goal)
// Include addresses for investors' token reserve funds and for releaseTime
constructor(
uint256 rate,
address payable wallet,
SLPRcoin token,
uint256 cap,
uint256 openingTime,
uint256 closingTime,
uint256 goal,
address _foundersFund,
address _foundationFund,
address _partnersFund,
uint256 _releaseTime
)
Crowdsale(rate, wallet, token)
CappedCrowdsale(cap)
TimedCrowdsale(openingTime, closingTime)
RefundableCrowdsale(goal)
public
{
require(goal <= cap);
foundersFund = _foundersFund;
foundationFund = _foundationFund;
partnersFund = _partnersFund;
releaseTime = _releaseTime;
}
/**
* Create public function to view current investor contriutions by address
* @dev Returns the amount contributed so far by a specific user.
* @param _beneficiary Address of contributor
* @return User contribution so far
*/
function getUserContribution(address payable _beneficiary)
public view returns (uint256)
{
return contributions[_beneficiary];
}
/**
*@dev Allows admin to update the crowdsale stage
* @param _stage Crowdsale stage
*/
function setCrowdsaleStage(uint _stage) public {
//require(msg.sender == owner, "You are not the owner");
if(uint(CrowdsaleStage.PreICO) == _stage) {
stage = CrowdsaleStage.PreICO;
} else if (uint(CrowdsaleStage.ICO) == _stage) {
stage = CrowdsaleStage.ICO;
}
if(stage == CrowdsaleStage.PreICO) {
uint256 rate = 500;
} else if (stage == CrowdsaleStage.ICO) {
uint256 rate = 250;
}
}
/**
* @dev forwards funds to the wallet during the PreICO stage, then the refund vault during ICO stage
*/
function _forwardFunds(address payable wallet) internal {
if(stage == CrowdsaleStage.PreICO) {
wallet.transfer(msg.value);
} else if (stage == CrowdsaleStage.ICO) {
super._forwardFunds();
}
}
/**
* @dev Extend parent behavior requiring purchase to respect investor min/max funding cap.
* @param _beneficiary Token purchaser
* @param _weiAmount Amount of wei contributed
*/
function _preValidatePurchase(
address payable _beneficiary,
uint256 _weiAmount
)
internal
{
super._preValidatePurchase(_beneficiary, _weiAmount);
uint256 _existingContribution = contributions[_beneficiary];
uint256 _newContribution = _existingContribution.add(_weiAmount);
require(_newContribution >= investorMinCap && _newContribution <= investorHardCap);
contributions[_beneficiary] = _newContribution;
}
/**
* @return the amount of wei raised.
*/
function fundsRaised() public view returns (uint256) {
return _weiRaised;
}
function _buyTokens(address beneficiary, uint256 amount) public nonReentrant payable {
// super.buyTokens(beneficiary);
uint256 weiAmount = amount;
_preValidatePurchase(beneficiary, weiAmount);
// calculate token amount to be created
uint256 tokens = _getTokenAmount(weiAmount);
// update state
_weiRaised = _weiRaised.add(weiAmount);
_processPurchase(beneficiary, tokens);
emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
_updatePurchasingState(beneficiary, weiAmount);
_forwardFunds();
_postValidatePurchase(beneficiary, weiAmount);
}
/**
*@dev enables token transfers, called when owner calls finalize()
*/
function finalization( ) internal {
/**Future enhancements below will enable token transfers when goal is reached and Distribution to preset funds once
* releaseTime expires
*/
//if(goalReached()) {
//ERC20Mintable _mintableToken = ERC20Mintable(token);
//uint256 _alreadyMinted = _mintableToken.totalSupply();
//uint256 _finalTotalSupply = _alreadyMinted.div(tokenSalePercentage).mul(100);
//foundersTimelock = new TokenTimelock(token, foundersFund, releaseTime);
//foundationTimelock = new TokenTimelock(token, foundationFund, releaseTime);
//partnersTimelock = new TokenTimelock(token, partnersFund, releaseTime);
//_mintableToken.mint(address(foundersTimelock), _finalTotalSupply.mul(foundersPercentage).div(100));
//_mintableToken.mint(address(foundationTimelock), _finalTotalSupply.mul(foundationPercentage).div(100));
//_mintableToken.mint(address(partnersTimelock), _finalTotalSupply.mul(partnersPercentage).div(100));
//_mintableToken.mint(foundersTimelock, _finalTotalSupply.div(foundersPercentage));
//_mintableToken.mint(foundationTimelock, _finalTotalSupply.div(foundationPercentage));
//_mintableToken.mint(partnersTimelock, _finalTotalSupply.div(partnersPercentage));
//_mintableToken.mint();
//ERC20Pausable _pausableToken = ERC20Pausable(token);
//_pausableToken.unpause();
//_pausableToken.transferOwnership(wallet);
//_mintableToken.transferOwnership(wallet);
//}
super._finalization();
}
/**
* @dev fallback function
*/
function () external payable {
}
}
contract SLPRcoinCrowdSaleDeployer {
address public token_sale_address;
address public token_address;
uint fakenow = now;
constructor(
// @TODO: Fill in the constructor parameters!
string memory name,
string memory symbol,
uint256 rate,
address payable wallet,
//SLPRcoin token,
uint256 cap,
//uint256 openingTime,
//uint256 closingTime,
uint256 goal,
address _foundersFund,
address _foundationFund,
address _partnersFund
//uint256 _releaseTime
// block_timestamp "now" will be passed as opening_time directly in the function call instead of creating a variable
//closing time is also passed via now + the duration. in this case we made the duration 1 hour for testing purposes
)
public
{
// @TODO: create the SLPRcoin and keep its address handy
// Create the SLPRcoin by defining a variable like `SLPRcoin token` and setting it to equal new SLPRcoin().
// Inside of the parameters of new SLPRcoin, pass in the name and symbol variables.
// For the initial_supply variable that SLPRcoin expects, pass in 0
SLPRcoin token = new SLPRcoin(name, symbol, 0);
// Then, store the address of the token by using token_address = address(token).
// This will allow us to easily fetch the token's address for later from the deploying contract.
token_address = address(token);
// @TODO: create the SLPRcoinCrowdSale and tell it about the token,
// set the goal, and set the open and close times to now and now + 24 weeks.
SLPRcoinCrowdSale slpr_sale = new SLPRcoinCrowdSale(rate, wallet, token, cap, fakenow, fakenow + 1 days, goal, _foundersFund, _foundationFund, _partnersFund, fakenow + 104 weeks);
token_sale_address = address(slpr_sale);
// make the SLPRcoinCrowdSale contract a minter, then have the SLPRcoinCrowdSaleDeployer renounce its minter role
token.addMinter(token_sale_address);
token.addMinter(wallet);
token.renounceMinter();
// make the SLPRcoinCrowdSale contract the Whitelist Admin, then have the SLPRcoinCrowdSaleDeployer renounce its
// Whitelist Admin role.
slpr_sale.addWhitelistAdmin(token_sale_address);
slpr_sale.addWhitelistAdmin(wallet);
slpr_sale.renounceWhitelistAdmin();
// Give owner rights to the SLPRcoinCrowdSale contract
//SLPRcoinCrowdSaleDeployer.transferOwnership(wallet);
}
}