2019-09-25 13:59:52 +00:00
|
|
|
/*
|
|
|
|
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";
|
|
|
|
|
2019-10-23 20:10:12 +00:00
|
|
|
abstract contract TokenCreationInterface {
|
2019-09-25 13:59:52 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
// string _tokenName,
|
|
|
|
// string _tokenSymbol,
|
|
|
|
// uint _decimalPlaces
|
|
|
|
// );
|
|
|
|
|
|
|
|
/// @notice Create Token with `_tokenHolder` as the initial owner of the Token
|
|
|
|
/// @param _tokenHolder The address of the Tokens's recipient
|
2019-12-09 16:28:57 +00:00
|
|
|
/// @return success Whether the token creation was successful
|
2019-11-05 17:25:34 +00:00
|
|
|
function createTokenProxy(address payable _tokenHolder) payable virtual public returns (bool success);
|
2019-09-25 13:59:52 +00:00
|
|
|
|
|
|
|
/// @notice Refund `msg.sender` in the case the Token Creation did
|
|
|
|
/// not reach its minimum fueling goal
|
2019-11-05 17:25:34 +00:00
|
|
|
function refund() virtual public;
|
2019-09-25 13:59:52 +00:00
|
|
|
|
2019-12-09 16:28:57 +00:00
|
|
|
/// @return divisor The divisor used to calculate the token creation rate during
|
2019-09-25 13:59:52 +00:00
|
|
|
/// the creation phase
|
2019-11-05 17:25:34 +00:00
|
|
|
function divisor() public virtual view returns (uint divisor);
|
2019-09-25 13:59:52 +00:00
|
|
|
|
|
|
|
event FuelingToDate(uint value);
|
|
|
|
event CreatedToken(address indexed to, uint amount);
|
|
|
|
event Refund(address indexed to, uint value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
contract TokenCreation is TokenCreationInterface, Token {
|
|
|
|
constructor(
|
|
|
|
uint _minTokensToCreate,
|
|
|
|
uint _closingTime,
|
|
|
|
address _privateCreation,
|
|
|
|
string memory _tokenName,
|
|
|
|
string memory _tokenSymbol,
|
|
|
|
uint8 _decimalPlaces) public {
|
|
|
|
|
|
|
|
closingTime = _closingTime;
|
|
|
|
minTokensToCreate = _minTokensToCreate;
|
|
|
|
privateCreation = _privateCreation;
|
|
|
|
extraBalance = new ManagedAccount(address(this), true);
|
|
|
|
name = _tokenName;
|
|
|
|
symbol = _tokenSymbol;
|
|
|
|
decimals = _decimalPlaces;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-09-16 12:33:43 +00:00
|
|
|
function createTokenProxy(address payable _tokenHolder) payable public
|
|
|
|
override returns (bool success) {
|
2019-09-25 13:59:52 +00:00
|
|
|
if (now < closingTime && msg.value > 0
|
|
|
|
&& (privateCreation == 0x0000000000000000000000000000000000000000 || privateCreation == msg.sender)) {
|
|
|
|
|
|
|
|
uint token = (msg.value * 20) / divisor();
|
|
|
|
address(extraBalance).call.value(msg.value - token)("");
|
|
|
|
balances[_tokenHolder] += token;
|
|
|
|
totalSupply += token;
|
|
|
|
weiGiven[_tokenHolder] += msg.value;
|
|
|
|
emit CreatedToken(_tokenHolder, token);
|
|
|
|
if (totalSupply >= minTokensToCreate && !isFueled) {
|
|
|
|
isFueled = true;
|
|
|
|
emit FuelingToDate(totalSupply);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
revert();
|
|
|
|
}
|
|
|
|
|
2019-09-16 12:33:43 +00:00
|
|
|
function refund() public override {
|
2019-09-25 13:59:52 +00:00
|
|
|
if (now > closingTime && !isFueled) {
|
|
|
|
// Get extraBalance - will only succeed when called for the first time
|
|
|
|
if (address(extraBalance).balance >= extraBalance.accumulatedInput())
|
|
|
|
extraBalance.payOut(address(this), extraBalance.accumulatedInput());
|
|
|
|
|
|
|
|
// Execute refund
|
|
|
|
(bool success,) = msg.sender.call.value(weiGiven[msg.sender])("");
|
|
|
|
if (success) {
|
|
|
|
emit Refund(msg.sender, weiGiven[msg.sender]);
|
|
|
|
totalSupply -= balances[msg.sender];
|
|
|
|
balances[msg.sender] = 0;
|
|
|
|
weiGiven[msg.sender] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-16 12:33:43 +00:00
|
|
|
function divisor() public override view returns (uint divisor) {
|
2019-09-25 13:59:52 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
2019-11-05 17:25:34 +00:00
|
|
|
receive() external virtual payable {
|
2019-09-25 13:59:52 +00:00
|
|
|
}
|
|
|
|
}
|