Contract Name:
CoVEXTokenERC223
Contract Source Code:
File 1 of 1 : CoVEXTokenERC223
pragma solidity ^0.4.18;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract ERC223 {
uint public totalSupply;
function balanceOf(address who) constant returns (uint);
function name() constant returns (string _name);
function symbol() constant returns (string _symbol);
function decimals() constant returns (uint8 _decimals);
function totalSupply() constant returns (uint256 _supply);
function transfer(address to, uint value) returns (bool ok);
function transfer(address to, uint value, bytes data) returns (bool ok);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event ERC223Transfer(address indexed _from, address indexed _to, uint256 _value, bytes _data);
}
contract ContractReceiver {
function tokenFallback(address _from, uint _value, bytes _data);
}
contract ERC223Token is ERC223 {
using SafeMath for uint;
mapping(address => uint) balances;
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
// Function to access name of token .
function name() constant returns (string _name) {
return name;
}
// Function to access symbol of token .
function symbol() constant returns (string _symbol) {
return symbol;
}
// Function to access decimals of token .
function decimals() constant returns (uint8 _decimals) {
return decimals;
}
// Function to access total supply of tokens .
function totalSupply() constant returns (uint256 _totalSupply) {
return totalSupply;
}
// Function that is called when a user or another contract wants to transfer funds .
function transfer(address _to, uint _value, bytes _data) returns (bool success) {
if(isContract(_to)) {
return transferToContract(_to, _value, _data);
}
else {
return transferToAddress(_to, _value, _data);
}
}
// Standard function transfer similar to ERC20 transfer with no _data .
// Added due to backwards compatibility reasons .
function transfer(address _to, uint _value) returns (bool success) {
//standard function transfer similar to ERC20 transfer with no _data
//added due to backwards compatibility reasons
bytes memory empty;
if(isContract(_to)) {
return transferToContract(_to, _value, empty);
}
else {
return transferToAddress(_to, _value, empty);
}
}
//assemble the given address bytecode. If bytecode exists then the _addr is a contract.
function isContract(address _addr) private returns (bool is_contract) {
uint length;
assembly {
//retrieve the size of the code on target address, this needs assembly
length := extcodesize(_addr)
}
if(length>0) {
return true;
}
else {
return false;
}
}
//function that is called when transaction target is an address
function transferToAddress(address _to, uint _value, bytes _data) private returns (bool success) {
if (balanceOf(msg.sender) < _value) revert();
balances[msg.sender] = balanceOf(msg.sender).sub(_value);
balances[_to] = balanceOf(_to).add(_value);
Transfer(msg.sender, _to, _value);
ERC223Transfer(msg.sender, _to, _value, _data);
return true;
}
//function that is called when transaction target is a contract
function transferToContract(address _to, uint _value, bytes _data) private returns (bool success) {
if (balanceOf(msg.sender) < _value) revert();
balances[msg.sender] = balanceOf(msg.sender).sub(_value);
balances[_to] = balanceOf(_to).add(_value);
ContractReceiver reciever = ContractReceiver(_to);
reciever.tokenFallback(msg.sender, _value, _data);
Transfer(msg.sender, _to, _value);
ERC223Transfer(msg.sender, _to, _value, _data);
return true;
}
function balanceOf(address _owner) constant returns (uint balance) {
return balances[_owner];
}
}
contract CoVEXTokenERC223 is ERC223Token{
using SafeMath for uint256;
string public name = "CoVEX Coin";
string public symbol = "CoVEX";
uint256 public decimals = 18;
// 250M
uint256 public totalSupply = 250*1000000 * (uint256(10) ** decimals);
uint256 public totalRaised; // total ether raised (in wei)
uint256 public startTimestamp; // timestamp after which ICO will start
uint256 public durationSeconds; // 1 month= 1 * 30 * 24 * 60 * 60
uint256 public maxCap;
uint256 coinsPerETH;
mapping(address => uint) etherBalance;
mapping(uint => uint) public weeklyRewards;
uint256 minPerUser = 0.1 ether;
uint256 maxPerUser = 100 ether;
/**
* Address which will receive raised funds
* and owns the total supply of tokens
*/
address public fundsWallet;
function CoVEXTokenERC223() {
fundsWallet = msg.sender;
startTimestamp = now;
durationSeconds = 0; //admin can set it later
//initially assign all tokens to the fundsWallet
balances[fundsWallet] = totalSupply;
Transfer(0x0, fundsWallet, totalSupply);
}
function() isIcoOpen checkMinMax payable{
totalRaised = totalRaised.add(msg.value);
uint256 tokenAmount = calculateTokenAmount(msg.value);
balances[fundsWallet] = balances[fundsWallet].sub(tokenAmount);
balances[msg.sender] = balances[msg.sender].add(tokenAmount);
etherBalance[msg.sender] = etherBalance[msg.sender].add(msg.value);
Transfer(fundsWallet, msg.sender, tokenAmount);
// immediately transfer ether to fundsWallet
fundsWallet.transfer(msg.value);
}
function calculateTokenAmount(uint256 weiAmount) constant returns(uint256) {
uint256 tokenAmount = weiAmount.mul(coinsPerETH);
// setting rewards is possible only for 4 weeks
for (uint i = 1; i <= 4; i++) {
if (now <= startTimestamp + (i * 7 days)) {
return tokenAmount.mul(100+weeklyRewards[i]).div(100);
}
}
return tokenAmount;
}
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function adminBurn(uint256 _value) public {
require(_value <= balances[msg.sender]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply = totalSupply.sub(_value);
Transfer(burner, address(0), _value);
}
function adminAddICO(uint256 _startTimestamp, uint256 _durationSeconds,
uint256 _coinsPerETH, uint256 _maxCap, uint _week1Rewards,
uint _week2Rewards, uint _week3Rewards, uint _week4Rewards) isOwner{
startTimestamp = _startTimestamp;
durationSeconds = _durationSeconds;
coinsPerETH = _coinsPerETH;
maxCap = _maxCap * 1 ether;
weeklyRewards[1] = _week1Rewards;
weeklyRewards[2] = _week2Rewards;
weeklyRewards[3] = _week3Rewards;
weeklyRewards[4] = _week4Rewards;
// reset totalRaised
totalRaised = 0;
}
modifier isIcoOpen() {
require(now >= startTimestamp);
require(now <= (startTimestamp + durationSeconds));
require(totalRaised <= maxCap);
_;
}
modifier checkMinMax(){
require(msg.value >= minPerUser);
require(msg.value <= maxPerUser);
_;
}
modifier isOwner(){
require(msg.sender == fundsWallet);
_;
}
}