-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpyceCrowdsale.sol
270 lines (214 loc) · 7.43 KB
/
SpyceCrowdsale.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
pragma solidity ^0.4.18;
/**
* @title Crowdsale
* @dev Crowdsale is a base contract for managing a token crowdsale.
* Crowdsales have a start and end timestamps, where investors can make
* token purchases and the crowdsale will assign them tokens based
* on a token per ETH rate. Funds collected are forwarded to a wallet
* as they arrive.
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) onlyOwner public {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
interface Token {
function transfer(address _to, uint256 _amount) external returns (bool success);
function balanceOf(address _owner) external view returns (uint256 balance);
function decimals() external view returns (uint8);
}
contract SpyceCrowdsale is Ownable{
using SafeMath for uint256;
// The token being sold
Token public token;
// start and end timestamps where investments are allowed (both inclusive)
uint256 public startTime;
uint256 public endTime;
// address where funds are collected
// address where tokens are deposited and from where we send tokens to buyers
address public wallet;
// how many token units a buyer gets per wei
uint256 public ratePerWei = 10204;
// amount of raised money in wei
uint256 public weiRaised;
//To check whether the contract has been powered up
bool contractPoweredUp = false;
uint256 TOKENS_SOLD;
uint256 maxTokensToSale;
bool isCrowdsalePaused = false;
/**
* event for token purchase logging
* @param purchaser who paid for the tokens
* @param beneficiary who got the tokens
* @param value weis paid for purchase
* @param amount amount of tokens purchased
*/
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
//modifiers
modifier nonZeroAddress(address _to) {
require(_to != 0x0);
_;
}
modifier nonZeroEth() {
require(msg.value > 0);
_;
}
function SpyceCrowdsale(address _tokenToBeUsed, address _wallet) public nonZeroAddress(_tokenToBeUsed) nonZeroAddress(_wallet)
{
owner = _wallet;
wallet = _wallet;
token = Token(_tokenToBeUsed);
}
// fallback function can be used to buy tokens
function () public payable {
buyTokens(msg.sender);
}
// low level token purchase function
// Minimum purchase can be of 1 ETH
function buyTokens(address beneficiary) public payable nonZeroAddress(beneficiary) nonZeroEth{
require (contractPoweredUp == true);
require(isCrowdsalePaused == false);
require(validPurchase());
require(TOKENS_SOLD<maxTokensToSale);
uint256 weiAmount = msg.value;
// calculate token amount to be created
uint256 tokens = weiAmount.mul(ratePerWei);
require(TOKENS_SOLD+tokens<=maxTokensToSale);
// update state
weiRaised = weiRaised.add(weiAmount);
token.transfer(beneficiary, tokens);
TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
TOKENS_SOLD = TOKENS_SOLD.add(tokens);
forwardFunds();
}
// send ether to the fund collection wallet
// override to create custom fund forwarding mechanisms
function forwardFunds() internal {
wallet.transfer(msg.value);
}
// @return true if the transaction can buy tokens
function validPurchase() internal constant returns (bool) {
bool withinPeriod = now >= startTime && now <= endTime;
bool nonZeroPurchase = msg.value != 0;
return withinPeriod && nonZeroPurchase;
}
// @return true if crowdsale event has ended
function hasEnded() public constant returns (bool) {
return now > endTime;
}
/**
* function to change the end date & time
* can only be called from owner wallet
**/
function changeEndTime(uint256 endTimeUnixTimestamp) public onlyOwner returns(bool) {
endTime = endTimeUnixTimestamp;
}
/**
* function to change the start date & time
* can only be called from owner wallet
**/
function changeStartTime(uint256 startTimeUnixTimestamp) public onlyOwner returns(bool) {
startTime = startTimeUnixTimestamp;
}
/**
* function to change the price rate
* can only be called from owner wallet
**/
function setPriceRate(uint256 newPrice) public onlyOwner returns (bool) {
ratePerWei = newPrice;
}
/**
* function to pause the crowdsale
* can only be called from owner wallet
**/
function pauseCrowdsale() public onlyOwner returns(bool) {
isCrowdsalePaused = true;
}
/**
* function to resume the crowdsale if it is paused
* can only be called from owner wallet
* if the crowdsale has been stopped, this function would not resume it
**/
function resumeCrowdsale() public onlyOwner returns (bool) {
isCrowdsalePaused = false;
}
/**
* Remaining tokens for sale
**/
function remainingTokensForSale() public constant returns (uint) {
return maxTokensToSale - TOKENS_SOLD;
}
/**
*@dev To power up the contract
* This will start the sale
* This will set the end time of the sale
* It will also check whether the contract has required number of tokens assigned to it or not
*/
function powerUpContract(uint _startTime, uint _endTime, uint _rate, uint _tokensAvailableInThisRound) public onlyOwner
{
require(_endTime > _startTime);
require(_rate > 0 && _tokensAvailableInThisRound > 0);
startTime = _startTime;
endTime = _endTime;
// Contract should have enough SPYCE credits
require(token.balanceOf(this) >= _tokensAvailableInThisRound * 10 ** 18);
ratePerWei = _rate;
contractPoweredUp = true;
maxTokensToSale = _tokensAvailableInThisRound * 10 ** 18;
TOKENS_SOLD = 0;
}
/**
* This will pull back all the tokens assigned to the contract back in the owner wallet
* This should be done in case there are unsold tokens and the crowdsale is over
**/
function pullUnsoldTokensBackToOwnerWallet() public onlyOwner
{
require(token.balanceOf(this)>0);
uint bal = token.balanceOf(this);
token.transfer(wallet,bal);
}
}