Spaces:
Runtime error
Runtime error
File size: 15,414 Bytes
ee7776a |
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 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
pragma solidity ^0.4.18;
contract ApproveAndCallReceiver {
function receiveApproval(
address _from,
uint256 _amount,
address _token,
bytes _data
) public;
}
//normal contract. already compiled as bin
contract Controlled {
modifier onlyController {
require(msg.sender == controller);
_;
}
address public controller;
function Controlled() public {
controller = msg.sender;
}
function changeController(address _newController) onlyController public {
controller = _newController;
}
}
contract ERC20Token {
/// total amount of tokens
uint256 public totalSupply;
//function totalSupply() public constant returns (uint256 balance);
/// @param _owner The address from which the balance will be retrieved
/// @return The balance
mapping (address => uint256) public balanceOf;
// function balanceOf(address _owner) public constant returns (uint256 balance);
/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _value) public returns (bool success);
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
/// @notice `msg.sender` approves `_spender` to spend `_value` tokens
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of tokens to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _value) public returns (bool success);
/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent
mapping (address => mapping (address => uint256)) public allowance;
//function allowance(address _owner, address _spender) public constant returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract TokenI is ERC20Token, Controlled {
string public name; //The Token's name: e.g. DigixDAO Tokens
uint8 public decimals; //Number of decimals of the smallest unit
string public symbol; //An identifier: e.g. REP
// ERC20 Methods
/// @notice `msg.sender` approves `_spender` to send `_amount` tokens on
/// its behalf, and then a function is triggered in the contract that is
/// being approved, `_spender`. This allows users to use their tokens to
/// interact with contracts in one function call instead of two
/// @param _spender The address of the contract able to transfer the tokens
/// @param _amount The amount of tokens to be approved for transfer
/// @return True if the function call was successful
function approveAndCall(
address _spender,
uint256 _amount,
bytes _extraData
) public returns (bool success);
// Generate and destroy tokens
/// @notice Generates `_amount` tokens that are assigned to `_owner`
/// @param _owner The address that will be assigned the new tokens
/// @param _amount The quantity of tokens generated
/// @return True if the tokens are generated correctly
function generateTokens(address _owner, uint _amount) public returns (bool);
/// @notice Burns `_amount` tokens from `_owner`
/// @param _owner The address that will lose the tokens
/// @param _amount The quantity of tokens to burn
/// @return True if the tokens are burned correctly
function destroyTokens(address _owner, uint _amount) public returns (bool);
}
contract Token is TokenI {
struct FreezeInfo {
address user;
uint256 amount;
}
//Key1: step(募资阶段); Key2: user sequence(用户序列)
mapping (uint8 => mapping (uint8 => FreezeInfo)) public freezeOf; //所有锁仓,key 使用序号向上增加,方便程序查询。
mapping (uint8 => uint8) public lastFreezeSeq; //最后的 freezeOf 键值。key: step; value: sequence
mapping (address => uint256) public airdropOf;//空投用户
address public owner;
bool public paused=false;//是否暂停私募
uint256 public minFunding = 1 ether; //最低起投额度
uint256 public airdropQty=0;//每个账户空投获得的量
uint256 public airdropTotalQty=0;//总共发放的空投代币数量
uint256 public tokensPerEther = 10000;//1eth兑换多少代币
address private vaultAddress;//存储众筹ETH的地址
uint256 public totalCollected = 0;//已经募到ETH的总数量
/* This generates a public event on the blockchain that will notify clients */
//event Transfer(address indexed from, address indexed to, uint256 value);
/* This notifies clients about the amount burnt */
event Burn(address indexed from, uint256 value);
/* This notifies clients about the amount frozen */
event Freeze(address indexed from, uint256 value);
/* This notifies clients about the amount unfrozen */
event Unfreeze(address indexed from, uint256 value);
event Payment(address sender, uint256 _ethAmount, uint256 _tokenAmount);
/* Initializes contract with initial supply tokens to the creator of the contract */
function Token(
uint256 initialSupply,
string tokenName,
uint8 decimalUnits,
string tokenSymbol,
address _vaultAddress
) public {
require(_vaultAddress != 0);
totalSupply = initialSupply * 10 ** uint256(decimalUnits);
balanceOf[msg.sender] = totalSupply;
name = tokenName;
symbol = tokenSymbol;
decimals = decimalUnits;
owner = msg.sender;
vaultAddress=_vaultAddress;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
modifier realUser(address user){
if(user == 0x0){
revert();
}
_;
}
modifier moreThanZero(uint256 _value){
if (_value <= 0){
revert();
}
_;
}
/// @dev Internal function to determine if an address is a contract
/// @param _addr The address being queried
/// @return True if `_addr` is a contract
function isContract(address _addr) constant internal returns(bool) {
uint size;
if (_addr == 0) {
return false;
}
assembly {
size := extcodesize(_addr)
}
return size>0;
}
/* Send coins */
function transfer(address _to, uint256 _value) realUser(_to) moreThanZero(_value) public returns (bool) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
require(balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows
balanceOf[msg.sender] = balanceOf[msg.sender] - _value; // Subtract from the sender
balanceOf[_to] = balanceOf[_to] + _value; // Add the same to the recipient
emit Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
return true;
}
/* Allow another contract to spend some tokens in your behalf */
function approve(address _spender, uint256 _value) moreThanZero(_value) public
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/**
* @notice `msg.sender` approves `_spender` to send `_amount` tokens on
* its behalf, and then a function is triggered in the contract that is
* being approved, `_spender`. This allows users to use their tokens to
* interact with contracts in one function call instead of two
* @param _spender The address of the contract able to transfer the tokens
* @param _amount The amount of tokens to be approved for transfer
* @return True if the function call was successful
*/
function approveAndCall(address _spender, uint256 _amount, bytes _extraData) public returns (bool success) {
require(approve(_spender, _amount));
ApproveAndCallReceiver(_spender).receiveApproval(
msg.sender,
_amount,
this,
_extraData
);
return true;
}
/* A contract attempts to get the coins */
function transferFrom(address _from, address _to, uint256 _value) realUser(_from) realUser(_to) moreThanZero(_value) public returns (bool success) {
require(balanceOf[_from] >= _value); // Check if the sender has enough
require(balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows
require(_value <= allowance[_from][msg.sender]); // Check allowance
balanceOf[_from] = balanceOf[_from] - _value; // Subtract from the sender
balanceOf[_to] = balanceOf[_to] + _value; // Add the same to the recipient
allowance[_from][msg.sender] = allowance[_from][msg.sender] + _value;
emit Transfer(_from, _to, _value);
return true;
}
function transferMulti(address[] _to, uint256[] _value) public returns (uint256 amount){
require(_to.length == _value.length);
uint8 len = uint8(_to.length);
for(uint8 j; j<len; j++){
amount += _value[j]*10**uint256(decimals);
}
require(balanceOf[msg.sender] >= amount);
for(uint8 i; i<len; i++){
address _toI = _to[i];
uint256 _valueI = _value[i]*10**uint256(decimals);
balanceOf[_toI] += _valueI;
balanceOf[msg.sender] -= _valueI;
emit Transfer(msg.sender, _toI, _valueI);
}
}
//冻结账户
function freeze(address _user, uint256 _value, uint8 _step) moreThanZero(_value) onlyController public returns (bool success) {
_value=_value*10**uint256(decimals);
return _freeze(_user,_value,_step);
}
function _freeze(address _user, uint256 _value, uint8 _step) moreThanZero(_value) private returns (bool success) {
//info256("balanceOf[_user]", balanceOf[_user]);
require(balanceOf[_user] >= _value);
balanceOf[_user] = balanceOf[_user] - _value;
freezeOf[_step][lastFreezeSeq[_step]] = FreezeInfo({user:_user, amount:_value});
lastFreezeSeq[_step]++;
emit Freeze(_user, _value);
return true;
}
//为用户解锁账户资金
function unFreeze(uint8 _step) onlyOwner public returns (bool unlockOver) {
//_end = length of freezeOf[_step]
uint8 _end = lastFreezeSeq[_step];
require(_end > 0);
unlockOver=false;
uint8 _start=0;
for(; _end>_start; _end--){
FreezeInfo storage fInfo = freezeOf[_step][_end-1];
uint256 _amount = fInfo.amount;
balanceOf[fInfo.user] += _amount;
delete freezeOf[_step][_end-1];
lastFreezeSeq[_step]--;
emit Unfreeze(fInfo.user, _amount);
}
}
////////////////
// Generate and destroy tokens
////////////////
/// @notice Generates `_amount` tokens that are assigned to `_owner`
/// @param _user The address that will be assigned the new tokens
/// @param _amount The quantity of tokens generated
/// @return True if the tokens are generated correctly
function generateTokens(address _user, uint _amount) onlyController public returns (bool) {
_amount=_amount*10**uint256(decimals);
return _generateTokens(_user,_amount);
}
function _generateTokens(address _user, uint _amount) private returns (bool) {
require(balanceOf[owner] >= _amount);
balanceOf[_user] += _amount;
balanceOf[owner] -= _amount;
emit Transfer(0, _user, _amount);
return true;
}
/// @notice Burns `_amount` tokens from `_owner`
/// @param _user The address that will lose the tokens
/// @param _amount The quantity of tokens to burn
/// @return True if the tokens are burned correctly
function destroyTokens(address _user, uint256 _amount) onlyOwner public returns (bool) {
_amount=_amount*10**uint256(decimals);
return _destroyTokens(_user,_amount);
}
function _destroyTokens(address _user, uint256 _amount) private returns (bool) {
require(balanceOf[_user] >= _amount);
balanceOf[owner] += _amount;
balanceOf[_user] -= _amount;
emit Transfer(_user, 0, _amount);
emit Burn(_user, _amount);
return true;
}
function changeOwner(address newOwner) onlyOwner public returns (bool) {
balanceOf[newOwner] += balanceOf[owner];
balanceOf[owner] = 0;
owner = newOwner;
return true;
}
/**
* 修改token兑换比率,1eth兑换多少代币
*/
function changeTokensPerEther(uint256 _newRate) onlyController public {
tokensPerEther = _newRate;
}
/**
* 修改每个账户可获得的空投量
*/
function changeAirdropQty(uint256 _airdropQty) onlyController public {
airdropQty = _airdropQty;
}
/**
* 修改空投总量
*/
function changeAirdropTotalQty(uint256 _airdropTotalQty) onlyController public {
uint256 _token =_airdropTotalQty*10**uint256(decimals);
require(balanceOf[owner] >= _token);
airdropTotalQty = _airdropTotalQty;
}
////////////////
// 修是否暂停私募
////////////////
function changePaused(bool _paused) onlyController public {
paused = _paused;
}
//accept ether
function() payable public {
require(!paused);
address _user=msg.sender;
uint256 tokenValue;
if(msg.value==0){//空投
require(airdropQty>0);
require(airdropTotalQty>=airdropQty);
require(airdropOf[_user]==0);
tokenValue=airdropQty*10**uint256(decimals);
airdropOf[_user]=tokenValue;
airdropTotalQty-=airdropQty;
require(_generateTokens(_user, tokenValue));
emit Payment(_user, msg.value, tokenValue);
}else{
require(msg.value >= minFunding);//最低起投
require(msg.value % 1 ether==0);//只能投整数倍eth
totalCollected +=msg.value;
require(vaultAddress.send(msg.value));//Send the ether to the vault
tokenValue = (msg.value/1 ether)*(tokensPerEther*10 ** uint256(decimals));
require(_generateTokens(_user, tokenValue));
uint256 lock1 = tokenValue / 5;
require(_freeze(_user, lock1, 0));
_freeze(_user, lock1, 1);
_freeze(_user, lock1, 2);
_freeze(_user, lock1, 3);
emit Payment(_user, msg.value, tokenValue);
}
}
}
|