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
| // Quantstamp Technologies Inc. (admin@chaindaily)
pragma solidity ^0.4.15;
import'./token/StandardToken.sol'; import'./token/BurnableToken.sol'; import'./ownership/Ownable.sol'; import'./math/SafeMath.sol';
/**
* The Quantstamp token (QSP) has a fixed supply and restricts the ability
* to transfer tokens until the owner has called the enableTransfer()
* function.
*
* The owner can associate the token with a token sale contract. In that
* case, the token balance is moved to the token sale contract, which
* in turn can transfer its tokens to contributors to the sale.
*/
contract QuantstampToken is StandardToken, BurnableToken, Ownable {
// Constants
string public constant name ="Quantstamp Token";
string public constant symbol ="QSP";
uint8 public constant decimals =18;
uint256 public constant INITIAL_SUPPLY =1000000000*(10** uint256(decimals));
uint256 public constant CROWDSALE_ALLOWANCE =650000000*(10** uint256(decimals));
uint256 public constant ADMIN_ALLOWANCE =350000000*(10** uint256(decimals));
// Properties
uint256 public crowdSaleAllowance;// the number of tokens available for crowdsales
uint256 public adminAllowance;// the number of tokens available for the administrator
address public crowdSaleAddr;// the address of a crowdsale currently selling this token
address public adminAddr;// the address of a crowdsale currently selling this token
bool public transferEnabled =false;// indicates if transferring tokens is enabled or not
// Modifiers
modifier onlyWhenTransferEnabled(){ if(!transferEnabled){
require(msg.sender== adminAddr || msg.sender== crowdSaleAddr); }
_; }
modifier validDestination(address _to){
require(_to != address(0x0));
require(_to != address(this));
_; }
/**
* Constructor - instantiates token supply and allocates balanace of
* to the owner (msg.sender).
*/ function QuantstampToken(address _admin){
totalSupply = INITIAL_SUPPLY;
crowdSaleAllowance = CROWDSALE_ALLOWANCE;
adminAllowance = ADMIN_ALLOWANCE;
// mint all tokens
balances[msg.sender]= totalSupply;
Transfer(address(0x0), msg.sender, totalSupply);
adminAddr = _admin;
approve(adminAddr, adminAllowance); }
/**
* Associates this token with a current crowdsale, giving the crowdsale
* an allowance of tokens from the crowdsale supply. This gives the
* crowdsale the ability to call transferFrom to transfer tokens to
* whomever has purchased them.
*
* Note that if _amountForSale is 0, then it is assumed that the full
* remaining crowdsale supply is made available to the crowdsale.
*
* @param _crowdSaleAddr The address of a crowdsale contract that will sell this token
* @param _amountForSale The supply of tokens provided to the crowdsale
*/ function setCrowdsale(address _crowdSaleAddr, uint256 _amountForSale) external onlyOwner {
require(!transferEnabled);
require(_amountForSale <=< span> crowdSaleAllowance);
// if 0, then full available crowdsale supply is assumed
uint amount =(_amountForSale ==0)? crowdSaleAllowance : _amountForSale;
// Clear allowance of old, and set allowance of new
approve(crowdSaleAddr,0);
approve(_crowdSaleAddr, amount);
crowdSaleAddr = _crowdSaleAddr; }
/**
* Enables the ability of anyone to transfer their tokens. This can
* only be called by the token owner. Once enabled, it is not
* possible to disable transfers.
*/ function enableTransfer() external onlyOwner {
transferEnabled =true;
crowdSaleAllowance =0;
adminAllowance =0; }
/**
* Overrides ERC20 transfer function with modifier that prevents the
* ability to transfer tokens until after transfers have been enabled.
*/ function transfer(address _to, uint256 _value) public onlyWhenTransferEnabled validDestination(_to) returns (bool){ returnsuper.transfer(_to, _value); }
/**
* Overrides ERC20 transferFrom function with modifier that prevents the
* ability to transfer tokens until after transfers have been enabled.
*/ function transferFrom(address _from, address _to, uint256 _value) public onlyWhenTransferEnabled validDestination(_to) returns (bool){
bool result =super.transferFrom(_from, _to, _value); if(result){ if(msg.sender== crowdSaleAddr)
crowdSaleAllowance = crowdSaleAllowance.sub(_value); if(msg.sender== adminAddr)
adminAllowance = adminAllowance.sub(_value); } return result; }
/**
* Overrides the transferOwnership function so that the balance of
* tokens of the old owner can be transferred to the new owner.
*
* @param newOwner The new owner of the token balance
*/ function transferOwnership(address newOwner) onlyOwner public { super.transferOwnership(newOwner); }
/**
* Overrides the burn function so that it cannot be called until after
* transfers have been enabled.
*
* @param _value The amount of tokens to burn in mini-QSP
*/ function burn(uint256 _value) public onlyWhenTransferEnabled { super.burn(_value);
Transfer(msg.sender, address(0x0), _value); } } |