-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpreSaleDraft.sol
231 lines (189 loc) · 6.79 KB
/
preSaleDraft.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
pragma solidity 0.4.19;
import "./token/ERC20/ERC20Basic.sol";
import "./token/ERC20/ERC20.sol";
import "./token/ERC20/MintableToken.sol";
import "./token/ERC20/ERC20.sol";
import "./token/Ownable.sol";
import "./contracts/ReentrancyGuard.sol";
contract QRMToken is MintableToken {
string public constant NAME = " QUARK MARKET ";
string public constant SYMBOL = "BSE";
uint32 public constant DECIMALS = 18;
event Burn(address indexed burner, uint256 value);
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function burn(uint256 _value) public {
require(_value > 0);
require(_value <= balances[msg.sender]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply = totalSupply.sub(_value);
Burn(burner, _value);
}
}
contract Stateful {
enum State {
Init,
PreIco,
PreIcoPaused,
preIcoFinished,
ICO,
salePaused,
CrowdsaleFinished,
companySold
}
State public state = State.Init;
event StateChanged(State oldState, State newState);
function setState(State newState) internal {
State oldState = state;
state = newState;
StateChanged(oldState, newState);
}
}
contract FiatContract {
function fETH(uint _id) public view returns (uint256);
function fUSD(uint _id) public view returns (uint256);
function fEUR(uint _id) public view returns (uint256);
function fGBP(uint _id) public view returns (uint256);
function updatedAt(uint _id) public view returns (uint);
}
contract Crowdsale is Ownable, ReentrancyGuard, Stateful {
using SafeMath for uint;
function Crowdsale(address _multisig) {
multisig = _multisig;
token = new QRMToken();
}
function () public payable {mintTokens();}
mapping (address => uint) preICOinvestors;
mapping (address => uint) iICOinvestors;
QRMToken public token;
uint256 public startICO;
uint256 public startPreICO;
uint256 public period;
uint256 public constant RATE_CENT = 2000000000000000;
uint256 public constant PRE_ICO_TOKEN_HARDCAP = 440000 * 1 ether;
uint256 public constant ICO_TOKEN_HARDCAP = 1540000 * 1 ether;
uint256 public collectedCent;
uint256 day = 86400; // sec in day
uint256 public soldTokens;
address multisig;
//TODO разобраться что за фиатный контракт
FiatContract public price = FiatContract(0x2CDe56E5c8235D6360CCbb0c57Ce248Ca9C80909);
// mainnet 0x8055d0504666e2B6942BeB8D6014c964658Ca591
// testnet 0x2CDe56E5c8235D6360CCbb0c57Ce248Ca9C80909
modifier saleIsOn() {
require((state == State.PreIco || state == State.ICO)
&&(now < startICO + period || now < startPreICO + period));
_;
}
modifier isUnderHardCap() {
require(soldTokens < getHardcap());
_;
}
function startCompanySell() onlyOwner {
require(state == State.CrowdsaleFinished);
setState(State.companySold);
}
// for mint tokens to USD investor
function usdSale(address _to, uint _valueUSD) onlyOwner {
uint256 valueCent = _valueUSD * 100;
uint256 tokensAmount = RATE_CENT.mul(valueCent);
collectedCent += valueCent;
token.mint(_to, tokensAmount);
if (state == State.ICO || state == State.preIcoFinished) {
iICOinvestors[_to] += tokensAmount;
} else {
preICOinvestors[_to] += tokensAmount;
}
soldTokens += tokensAmount;
}
function pauseSale() onlyOwner {
require(state == State.ICO);
setState(State.salePaused);
}
function pausePreSale() onlyOwner {
require(state == State.PreIco);
setState(State.PreIcoPaused);
}
function startPreIco(uint256 _period) onlyOwner {
require(_period != 0);
require(state == State.Init || state == State.PreIcoPaused);
startPreICO = now;
period = _period * day;
setState(State.PreIco);
}
function finishPreIco() onlyOwner {
require(state == State.PreIco);
setState(State.preIcoFinished);
bool isSent = multisig.call.gas(3000000).value(this.balance)();
require(isSent);
}
function startIco(uint256 _period) onlyOwner {
require(_period != 0);
startICO = now;
period = _period * day;
setState(State.ICO);
}
function finishICO() onlyOwner {
require(state == State.ICO);
setState(State.CrowdsaleFinished);
bool isSent = multisig.call.gas(3000000).value(this.balance)();
require(isSent);
}
function finishMinting() onlyOwner {
token.finishMinting();
}
function getDouble() nonReentrant {
require(state == State.ICO || state == State.companySold);
uint256 extraTokensAmount;
if (state == State.ICO) {
extraTokensAmount = preICOinvestors[msg.sender];
preICOinvestors[msg.sender] = 0;
token.mint(msg.sender, extraTokensAmount);
iICOinvestors[msg.sender] += extraTokensAmount;
}else {
if (state == State.companySold) {
extraTokensAmount = preICOinvestors[msg.sender] + iICOinvestors[msg.sender];
preICOinvestors[msg.sender] = 0;
iICOinvestors[msg.sender] = 0;
token.mint(msg.sender, extraTokensAmount);
}
}
}
function getHardcap() returns(uint256) {
if (state == State.PreIco) {
return PRE_ICO_TOKEN_HARDCAP;
}else {
if (state == State.ICO) {
return ICO_TOKEN_HARDCAP;
}
}
}
function mintTokens() public payable saleIsOn isUnderHardCap nonReentrant {
uint256 valueWEI = msg.value;
uint256 priceUSD = price.iUSD(0);
uint256 valueCent = valueWEI.div(priceUSD);
uint256 tokens = RATE_CENT.mul(valueCent);
uint256 hardcap = getHardcap();
if (soldTokens + tokens > hardcap) {
tokens = hardcap.sub(soldTokens);
valueCent = tokens.div(RATE_CENT);
valueWEI = valueCent.mul(priceUSD);
uint256 change = msg.value - valueWEI;
bool isSent = msg.sender.call.gas(30000000).value(change)();
require(isSent);
}
token.mint(msg.sender, tokens);
collectedCent += valueCent;
soldTokens += tokens;
if (state == State.PreIco) {
preICOinvestors[msg.sender] += tokens;
} else {
iICOinvestors[msg.sender] += tokens;
}
}
}