Contract Source Code:
File 1 of 1 : PlusCoin
pragma solidity ^0.4.13;
/**
* @title PlusCoin Contract
* @dev The main token contract
*/
contract PlusCoin {
address public owner; // Token owner address
mapping (address => uint256) public balances; // balanceOf
// mapping (address => mapping (address => uint256)) public allowance;
mapping (address => mapping (address => uint256)) allowed;
string public standard = 'PlusCoin 1.0';
string public constant name = "PlusCoin";
string public constant symbol = "PLC";
uint public constant decimals = 18;
uint public totalSupply;
uint public constant fpct_packet_size = 3300;
uint public ownerPrice = 40 * fpct_packet_size; //PRESALE_PRICE * 3 * fpct_packet_size;
State public current_state; // current token state
uint public soldAmount; // current sold amount (for current state)
uint public constant owner_MIN_LIMIT = 15000000 * fpct_packet_size * 1000000000000000000;
uint public constant TOKEN_PRESALE_LIMIT = 100000 * fpct_packet_size * 1000000000000000000;
uint public constant TOKEN_ICO1_LIMIT = 3000000 * fpct_packet_size * 1000000000000000000;
uint public constant TOKEN_ICO2_LIMIT = 3000000 * fpct_packet_size * 1000000000000000000;
uint public constant TOKEN_ICO3_LIMIT = 3000000 * fpct_packet_size * 1000000000000000000;
address public allowed_contract;
// States
enum State {
Created,
Presale,
ICO1,
ICO2,
ICO3,
Freedom,
Paused // only for first stages
}
//
// Events
// This generates a publics event on the blockchain that will notify clients
event Sent(address from, address to, uint amount);
event Buy(address indexed sender, uint eth, uint fbt);
event Withdraw(address indexed sender, address to, uint eth);
event StateSwitch(State newState);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
//
// Modifiers
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
modifier onlyAllowedContract() {
require(msg.sender == allowed_contract);
_;
}
modifier onlyOwnerBeforeFree() {
if(current_state != State.Freedom) {
require(msg.sender == owner);
}
_;
}
modifier inState(State _state) {
require(current_state == _state);
_;
}
//
// Functions
//
// Constructor
function PlusCoin() {
owner = msg.sender;
totalSupply = 25000000 * fpct_packet_size * 1000000000000000000;
balances[owner] = totalSupply;
current_state = State.Created;
soldAmount = 0;
}
// fallback function
function() payable {
require(current_state != State.Paused && current_state != State.Created && current_state != State.Freedom);
require(msg.value >= 1);
require(msg.sender != owner);
buyTokens(msg.sender);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) onlyOwner {
if (newOwner != address(0)) {
owner = newOwner;
}
}
function safeMul(uint a, uint b) internal returns (uint) {
uint c = a * b;
require(a == 0 || c / a == b);
return c;
}
function safeSub(uint a, uint b) internal returns (uint) {
require(b <= a);
return a - b;
}
function safeAdd(uint a, uint b) internal returns (uint) {
uint c = a + b;
require(c>=a && c>=b);
return c;
}
// Buy entry point
function buy() public payable {
require(current_state != State.Paused && current_state != State.Created && current_state != State.Freedom);
require(msg.value >= 1);
require(msg.sender != owner);
buyTokens(msg.sender);
}
// Payable function for buy coins from token owner
function buyTokens(address _buyer) public payable
{
require(current_state != State.Paused && current_state != State.Created && current_state != State.Freedom);
require(msg.value >= 1);
require(_buyer != owner);
uint256 wei_value = msg.value;
uint256 tokens = safeMul(wei_value, ownerPrice);
tokens = tokens;
uint256 currentSoldAmount = safeAdd(tokens, soldAmount);
if(current_state == State.Presale) {
require(currentSoldAmount <= TOKEN_PRESALE_LIMIT);
}
if(current_state == State.ICO1) {
require(currentSoldAmount <= TOKEN_ICO1_LIMIT);
}
if(current_state == State.ICO2) {
require(currentSoldAmount <= TOKEN_ICO2_LIMIT);
}
if(current_state == State.ICO3) {
require(currentSoldAmount <= TOKEN_ICO3_LIMIT);
}
require( (balances[owner] - tokens) >= owner_MIN_LIMIT );
balances[owner] = safeSub(balances[owner], tokens);
balances[_buyer] = safeAdd(balances[_buyer], tokens);
soldAmount = safeAdd(soldAmount, tokens);
owner.transfer(this.balance);
Buy(_buyer, msg.value, tokens);
}
function setOwnerPrice(uint128 _newPrice) public
onlyOwner
returns (bool success)
{
ownerPrice = _newPrice;
return true;
}
function setAllowedContract(address _contract_address) public
onlyOwner
returns (bool success)
{
allowed_contract = _contract_address;
return true;
}
// change state of token
function setTokenState(State _nextState) public
onlyOwner
returns (bool success)
{
bool canSwitchState
= (current_state == State.Created && _nextState == State.Presale)
|| (current_state == State.Presale && _nextState == State.ICO1)
|| (current_state == State.ICO1 && _nextState == State.ICO2)
|| (current_state == State.ICO2 && _nextState == State.ICO3)
|| (current_state == State.ICO3 && _nextState == State.Freedom)
//pause (allowed only 'any state->pause' & 'pause->presale' transition)
// || (current_state == State.Presale && _nextState == State.Paused)
// || (current_state == State.Paused && _nextState == State.Presale)
|| (current_state != State.Freedom && _nextState == State.Paused)
|| (current_state == State.Paused);
require(canSwitchState);
current_state = _nextState;
soldAmount = 0;
StateSwitch(_nextState);
return true;
}
function remaining_for_sale() public constant returns (uint256 remaining_coins) {
uint256 coins = 0;
if (current_state == State.Presale) {
coins = TOKEN_PRESALE_LIMIT - soldAmount;
}
if (current_state == State.ICO1) {
coins = TOKEN_PRESALE_LIMIT - soldAmount;
}
if (current_state == State.ICO2) {
coins = TOKEN_PRESALE_LIMIT - soldAmount;
}
if (current_state == State.ICO3) {
coins = TOKEN_PRESALE_LIMIT - soldAmount;
}
if (current_state == State.Freedom) {
coins = balances[owner] - owner_MIN_LIMIT;
}
return coins;
}
function get_token_state() public constant returns (State) {
return current_state;
}
function withdrawEther(address _to) public
onlyOwner
{
_to.transfer(this.balance);
}
/**
* ERC 20 token functions
*
* https://github.com/ethereum/EIPs/issues/20
*/
function transfer(address _to, uint256 _value)
onlyOwnerBeforeFree
returns (bool success)
{
if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
balances[msg.sender] -= _value;
balances[_to] += _value;
Transfer(msg.sender, _to, _value);
return true;
} else { return false; }
}
function transferFrom(address _from, address _to, uint256 _value)
onlyOwnerBeforeFree
returns (bool success)
{
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
balances[_to] += _value;
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
} else { return false; }
}
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner];
}
function approve(address _spender, uint256 _value)
onlyOwnerBeforeFree
returns (bool success)
{
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender)
onlyOwnerBeforeFree
constant returns (uint256 remaining)
{
return allowed[_owner][_spender];
}
///suicide & send funds to owner
function destroy() {
if (msg.sender == owner) {
suicide(owner);
}
}
}