pragma solidity ^0.4.24;
//
// MeshX Token
//
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
contract MeshXToken {
using SafeMath for uint256;
string public constant name = "MeshX";
string public constant symbol = "MSX";
uint public constant decimals = 18;
uint256 EthRate = 10 ** decimals;
uint256 Supply = 3000000000;
uint256 public totalSupply = Supply * EthRate;
uint256 public minInvEth = 2 ether;
uint256 public maxInvEth = 2000.0 ether;
uint256 public sellStartTime = 1533052800; // 2018/8/1
uint256 public sellDeadline1 = sellStartTime + 60 days;
uint256 public sellDeadline2 = sellDeadline1 + 60 days;
uint256 public freezeDuration = 180 days;
uint256 public ethRate1 = 3600;
uint256 public ethRate2 = 3000;
bool public running = true;
bool public buyable = true;
address owner;
mapping (address => mapping (address => uint256)) allowed;
mapping (address => bool) public whitelist;
mapping (address => uint256) whitelistLimit;
struct BalanceInfo {
uint256 balance;
uint256[] freezeAmount;
uint256[] releaseTime;
}
mapping (address => BalanceInfo) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
event BeginRunning();
event Pause();
event BeginSell();
event PauseSell();
event Burn(address indexed burner, uint256 val);
event Freeze(address indexed from, uint256 value);
constructor () public{
owner = msg.sender;
balances[owner].balance = totalSupply;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
modifier onlyWhitelist() {
require(whitelist[msg.sender] == true);
_;
}
modifier isRunning(){
require(running);
_;
}
modifier isNotRunning(){
require(!running);
_;
}
modifier isBuyable(){
require(buyable && now >= sellStartTime && now <= sellDeadline2);
_;
}
modifier isNotBuyable(){
require(!buyable || now < sellStartTime || now > sellDeadline2);
_;
}
// mitigates the ERC20 short address attack
modifier onlyPayloadSize(uint size) {
assert(msg.data.length >= size + 4);
_;
}
// 1eth = newRate tokens
function setPublicOfferPrice(uint256 _rate1, uint256 _rate2) onlyOwner public {
ethRate1 = _rate1;
ethRate2 = _rate2;
}
//
function setPublicOfferLimit(uint256 _minVal, uint256 _maxVal) onlyOwner public {
minInvEth = _minVal;
maxInvEth = _maxVal;
}
function setPublicOfferDate(uint256 _startTime, uint256 _deadLine1, uint256 _deadLine2) onlyOwner public {
sellStartTime = _startTime;
sellDeadline1 = _deadLine1;
sellDeadline2 = _deadLine2;
}
function transferOwnership(address _newOwner) onlyOwner public {
if (_newOwner != address(0)) {
owner = _newOwner;
}
}
function pause() onlyOwner isRunning public {
running = false;
emit Pause();
}
function start() onlyOwner isNotRunning public {
running = true;
emit BeginRunning();
}
function pauseSell() onlyOwner isBuyable isRunning public{
buyable = false;
emit PauseSell();
}
function beginSell() onlyOwner isNotBuyable isRunning public{
buyable = true;
emit BeginSell();
}
//
// _amount in MeshX,
//
function airDeliver(address _to, uint256 _amount) onlyOwner public {
require(owner != _to);
require(_amount > 0);
require(balances[owner].balance >= _amount);
// take big number as wei
if(_amount < Supply){
_amount = _amount * EthRate;
}
balances[owner].balance = balances[owner].balance.sub(_amount);
balances[_to].balance = balances[_to].balance.add(_amount);
emit Transfer(owner, _to, _amount);
}
function airDeliverMulti(address[] _addrs, uint256 _amount) onlyOwner public {
require(_addrs.length <= 255);
for (uint8 i = 0; i < _addrs.length; i++) {
airDeliver(_addrs[i], _amount);
}
}
function airDeliverStandalone(address[] _addrs, uint256[] _amounts) onlyOwner public {
require(_addrs.length <= 255);
require(_addrs.length == _amounts.length);
for (uint8 i = 0; i < _addrs.length; i++) {
airDeliver(_addrs[i], _amounts[i]);
}
}
//
// _amount, _freezeAmount in MeshX
//
function freezeDeliver(address _to, uint _amount, uint _freezeAmount, uint _freezeMonth, uint _unfreezeBeginTime ) onlyOwner public {
require(owner != _to);
require(_freezeMonth > 0);
uint average = _freezeAmount / _freezeMonth;
BalanceInfo storage bi = balances[_to];
uint[] memory fa = new uint[](_freezeMonth);
uint[] memory rt = new uint[](_freezeMonth);
if(_amount < Supply){
_amount = _amount * EthRate;
average = average * EthRate;
_freezeAmount = _freezeAmount * EthRate;
}
require(balances[owner].balance > _amount);
uint remainAmount = _freezeAmount;
if(_unfreezeBeginTime == 0)
_unfreezeBeginTime = now + freezeDuration;
for(uint i=0;i<_freezeMonth-1;i++){
fa[i] = average;
rt[i] = _unfreezeBeginTime;
_unfreezeBeginTime += freezeDuration;
remainAmount = remainAmount.sub(average);
}
fa[i] = remainAmount;
rt[i] = _unfreezeBeginTime;
bi.balance = bi.balance.add(_amount);
bi.freezeAmount = fa;
bi.releaseTime = rt;
balances[owner].balance = balances[owner].balance.sub(_amount);
emit Transfer(owner, _to, _amount);
emit Freeze(_to, _freezeAmount);
}
// buy tokens directly
function () external payable {
buyTokens();
}
//
function buyTokens() payable isRunning isBuyable onlyWhitelist public {
uint256 weiVal = msg.value;
address investor = msg.sender;
require(investor != address(0) && weiVal >= minInvEth && weiVal <= maxInvEth);
require(weiVal.add(whitelistLimit[investor]) <= maxInvEth);
uint256 amount = 0;
if(now > sellDeadline1)
amount = msg.value.mul(ethRate2);
else
amount = msg.value.mul(ethRate1);
whitelistLimit[investor] = weiVal.add(whitelistLimit[investor]);
balances[owner].balance = balances[owner].balance.sub(amount);
balances[investor].balance = balances[investor].balance.add(amount);
emit Transfer(owner, investor, amount);
}
function addWhitelist(address[] _addrs) public onlyOwner {
require(_addrs.length <= 255);
for (uint8 i = 0; i < _addrs.length; i++) {
if (!whitelist[_addrs[i]]){
whitelist[_addrs[i]] = true;
}
}
}
function balanceOf(address _owner) constant public returns (uint256) {
return balances[_owner].balance;
}
function freezeOf(address _owner) constant public returns (uint256) {
BalanceInfo storage bi = balances[_owner];
uint freezeAmount = 0;
uint t = now;
for(uint i=0;i< bi.freezeAmount.length;i++){
if(t < bi.releaseTime[i])
freezeAmount += bi.freezeAmount[i];
}
return freezeAmount;
}
function transfer(address _to, uint256 _amount) isRunning onlyPayloadSize(2 * 32) public returns (bool success) {
require(_to != address(0));
uint freezeAmount = freezeOf(msg.sender);
uint256 _balance = balances[msg.sender].balance.sub(freezeAmount);
require(_amount <= _balance);
balances[msg.sender].balance = balances[msg.sender].balance.sub(_amount);
balances[_to].balance = balances[_to].balance.add(_amount);
emit Transfer(msg.sender, _to, _amount);
return true;
}
function transferFrom(address _from, address _to, uint256 _amount) isRunning onlyPayloadSize(3 * 32) public returns (bool success) {
require(_from != address(0) && _to != address(0));
require(_amount <= allowed[_from][msg.sender]);
uint freezeAmount = freezeOf(_from);
uint256 _balance = balances[_from].balance.sub(freezeAmount);
require(_amount <= _balance);
balances[_from].balance = balances[_from].balance.sub(_amount);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amount);
balances[_to].balance = balances[_to].balance.add(_amount);
emit Transfer(_from, _to, _amount);
return true;
}
function approve(address _spender, uint256 _value) isRunning public returns (bool success) {
if (_value != 0 && allowed[msg.sender][_spender] != 0) {
return false;
}
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) constant public returns (uint256) {
return allowed[_owner][_spender];
}
function withdraw() onlyOwner public {
address myAddress = this;
require(myAddress.balance > 0);
owner.transfer(myAddress.balance);
emit Transfer(this, owner, myAddress.balance);
}
function burn(address burner, uint256 _value) onlyOwner public {
require(_value <= balances[msg.sender].balance);
balances[burner].balance = balances[burner].balance.sub(_value);
totalSupply = totalSupply.sub(_value);
Supply = totalSupply / EthRate;
emit Burn(burner, _value);
}
}
{
"compilationTarget": {
"MeshXToken.sol": "MeshXToken"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_addrs","type":"address[]"},{"name":"_amount","type":"uint256"}],"name":"airDeliverMulti","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"airDeliver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_freezeAmount","type":"uint256"},{"name":"_freezeMonth","type":"uint256"},{"name":"_unfreezeBeginTime","type":"uint256"}],"name":"freezeDeliver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_rate1","type":"uint256"},{"name":"_rate2","type":"uint256"}],"name":"setPublicOfferPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"freezeDuration","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_startTime","type":"uint256"},{"name":"_deadLine1","type":"uint256"},{"name":"_deadLine2","type":"uint256"}],"name":"setPublicOfferDate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"beginSell","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxInvEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"buyable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pauseSell","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"sellDeadline2","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"whitelist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"burner","type":"address"},{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_addrs","type":"address[]"},{"name":"_amounts","type":"uint256[]"}],"name":"airDeliverStandalone","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ethRate2","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ethRate1","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sellStartTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minVal","type":"uint256"},{"name":"_maxVal","type":"uint256"}],"name":"setPublicOfferLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"freezeOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"buyTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"minInvEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"running","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sellDeadline1","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_addrs","type":"address[]"}],"name":"addWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[],"name":"BeginRunning","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"BeginSell","type":"event"},{"anonymous":false,"inputs":[],"name":"PauseSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"val","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Freeze","type":"event"}]