forked from blockchainsllc/DAO
-
Notifications
You must be signed in to change notification settings - Fork 31
/
TokenCreation.sol
142 lines (121 loc) · 5.39 KB
/
TokenCreation.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
/*
This file is part of the DAO.
The DAO is free software: you can redistribute it and/or modify
it under the terms of the GNU lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The DAO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU lesser General Public License for more details.
You should have received a copy of the GNU lesser General Public License
along with the DAO. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Token Creation contract, used by the DAO to create its tokens and initialize
* its ether. Feel free to modify the divisor method to implement different
* Token Creation parameters
*/
import "./Token.sol";
import "./ManagedAccount.sol";
contract TokenCreationInterface {
// End of token creation, in Unix time
uint public closingTime;
// Minimum fueling goal of the token creation, denominated in tokens to
// be created
uint public minTokensToCreate;
// True if the DAO reached its minimum fueling goal, false otherwise
bool public isFueled;
// For DAO splits - if privateCreation is 0, then it is a public token
// creation, otherwise only the address stored in privateCreation is
// allowed to create tokens
address public privateCreation;
// hold extra ether which has been sent after the DAO token
// creation rate has increased
ManagedAccount public extraBalance;
// tracks the amount of wei given from each contributor (used for refund)
mapping (address => uint256) weiGiven;
/// @dev Constructor setting the minimum fueling goal and the
/// end of the Token Creation
/// @param _minTokensToCreate Minimum fueling goal in number of
/// Tokens to be created
/// @param _closingTime Date (in Unix time) of the end of the Token Creation
/// @param _privateCreation Zero means that the creation is public. A
/// non-zero address represents the only address that can create Tokens
/// (the address can also create Tokens on behalf of other accounts)
// This is the constructor: it can not be overloaded so it is commented out
// function TokenCreation(
// uint _minTokensTocreate,
// uint _closingTime,
// address _privateCreation
// );
/// @notice Create Token with `_tokenHolder` as the initial owner of the Token
/// @param _tokenHolder The address of the Tokens's recipient
/// @return Whether the token creation was successful
function createTokenProxy(address _tokenHolder) returns (bool success);
/// @notice Refund `msg.sender` in the case the Token Creation did
/// not reach its minimum fueling goal
function refund();
/// @return The divisor used to calculate the token creation rate during
/// the creation phase
function divisor() constant returns (uint divisor);
event FuelingToDate(uint value);
event CreatedToken(address indexed to, uint amount);
event Refund(address indexed to, uint value);
}
contract TokenCreation is TokenCreationInterface, Token {
function TokenCreation(
uint _minTokensToCreate,
uint _closingTime,
address _privateCreation) {
closingTime = _closingTime;
minTokensToCreate = _minTokensToCreate;
privateCreation = _privateCreation;
extraBalance = new ManagedAccount(address(this), true);
}
function createTokenProxy(address _tokenHolder) returns (bool success) {
if (now < closingTime && msg.value > 0
&& (privateCreation == 0 || privateCreation == msg.sender)) {
uint token = (msg.value * 20) / divisor();
extraBalance.call.value(msg.value - token)();
balances[_tokenHolder] += token;
totalSupply += token;
weiGiven[_tokenHolder] += msg.value;
CreatedToken(_tokenHolder, token);
if (totalSupply >= minTokensToCreate && !isFueled) {
isFueled = true;
FuelingToDate(totalSupply);
}
return true;
}
throw;
}
function refund() noEther {
if (now > closingTime && !isFueled) {
// Get extraBalance - will only succeed when called for the first time
if (extraBalance.balance >= extraBalance.accumulatedInput())
extraBalance.payOut(address(this), extraBalance.accumulatedInput());
// Execute refund
if (msg.sender.call.value(weiGiven[msg.sender])()) {
Refund(msg.sender, weiGiven[msg.sender]);
totalSupply -= balances[msg.sender];
balances[msg.sender] = 0;
weiGiven[msg.sender] = 0;
}
}
}
function divisor() constant returns (uint divisor) {
// The number of (base unit) tokens per wei is calculated
// as `msg.value` * 20 / `divisor`
// The fueling period starts with a 1:1 ratio
if (closingTime - 2 weeks > now) {
return 20;
// Followed by 10 days with a daily creation rate increase of 5%
} else if (closingTime - 4 days > now) {
return (20 + (now - (closingTime - 2 weeks)) / (1 days));
// The last 4 days there is a constant creation rate ratio of 1:1.5
} else {
return 30;
}
}
}