pragma solidity ^0.4.24;
contract ERC20Interface {
function totalSupply()
public
view
returns (uint256);
function balanceOf(
address _address)
public
view
returns (uint256 balance);
function allowance(
address _address,
address _to)
public
view
returns (uint256 remaining);
function transfer(
address _to,
uint256 _value)
public
returns (bool success);
function approve(
address _to,
uint256 _value)
public
returns (bool success);
function transferFrom(
address _from,
address _to,
uint256 _value)
public
returns (bool success);
event Transfer(
address indexed _from,
address indexed _to,
uint256 _value
);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
}
contract Owned {
address owner;
address newOwner;
uint32 transferCount;
event TransferOwnership(
address indexed _from,
address indexed _to
);
constructor() public {
owner = msg.sender;
transferCount = 0;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
function transferOwnership(
address _newOwner)
public
onlyOwner
{
newOwner = _newOwner;
}
function viewOwner()
public
view
returns (address)
{
return owner;
}
function viewTransferCount()
public
view
onlyOwner
returns (uint32)
{
return transferCount;
}
function isTransferPending()
public
view
returns (bool) {
require(
msg.sender == owner ||
msg.sender == newOwner);
return newOwner != address(0);
}
function acceptOwnership()
public
{
require(msg.sender == newOwner);
owner = newOwner;
newOwner = address(0);
transferCount++;
emit TransferOwnership(
owner,
newOwner
);
}
}
library SafeMath {
function add(
uint256 a,
uint256 b)
internal
pure
returns(uint256 c)
{
c = a + b;
require(c >= a);
}
function sub(
uint256 a,
uint256 b)
internal
pure
returns(uint256 c)
{
require(b <= a);
c = a - b;
}
function mul(
uint256 a,
uint256 b)
internal
pure
returns(uint256 c) {
c = a * b;
require(a == 0 || c / a == b);
}
function div(
uint256 a,
uint256 b)
internal
pure
returns(uint256 c) {
require(b > 0);
c = a / b;
}
}
contract ApproveAndCallFallBack {
function receiveApproval(
address _from,
uint256 _value,
address token,
bytes data)
public
returns (bool success);
}
contract Pausable is Owned {
event Pause();
event Unpause();
bool public paused = false;
modifier whenNotPaused() {
require(!paused);
_;
}
modifier whenPaused() {
require(paused);
_;
}
function pause() onlyOwner whenNotPaused public {
paused = true;
emit Pause();
}
function unpause() onlyOwner whenPaused public {
paused = false;
emit Unpause();
}
}
/**
* @title ERC1132 interface
* @dev see https://github.com/ethereum/EIPs/issues/1132
*/
contract ERC1132 {
/**
* @dev Reasons why a user's tokens have been locked
*/
mapping(address => bytes32[]) public lockReason;
/**
* @dev locked token structure
*/
struct lockToken {
uint256 amount;
uint256 validity;
bool claimed;
}
/**
* @dev Holds number & validity of tokens locked for a given reason for
* a specified address
*/
mapping(address => mapping(bytes32 => lockToken)) public locked;
/**
* @dev Records data of all the tokens Locked
*/
event Locked(
address indexed _of,
bytes32 indexed _reason,
uint256 _amount,
uint256 _validity
);
/**
* @dev Records data of all the tokens unlocked
*/
event Unlocked(
address indexed _of,
bytes32 indexed _reason,
uint256 _amount
);
/**
* @dev Locks a specified amount of tokens against an address,
* for a specified reason and time
* @param _reason The reason to lock tokens
* @param _amount Number of tokens to be locked
* @param _time Lock time in seconds
*/
function lock(bytes32 _reason, uint256 _amount, uint256 _time)
public returns (bool);
/**
* @dev Returns tokens locked for a specified address for a
* specified reason
*
* @param _of The address whose tokens are locked
* @param _reason The reason to query the lock tokens for
*/
function tokensLocked(address _of, bytes32 _reason)
public view returns (uint256 amount);
/**
* @dev Returns tokens locked for a specified address for a
* specified reason at a specific time
*
* @param _of The address whose tokens are locked
* @param _reason The reason to query the lock tokens for
* @param _time The timestamp to query the lock tokens for
*/
function tokensLockedAtTime(address _of, bytes32 _reason, uint256 _time)
public view returns (uint256 amount);
/**
* @dev Returns total tokens held by an address (locked + transferable)
* @param _of The address to query the total balance of
*/
function totalBalanceOf(address _of)
public view returns (uint256 amount);
/**
* @dev Extends lock for a specified reason and time
* @param _reason The reason to lock tokens
* @param _time Lock extension time in seconds
*/
function extendLock(bytes32 _reason, uint256 _time)
public returns (bool);
/**
* @dev Increase number of tokens locked for a specified reason
* @param _reason The reason to lock tokens
* @param _amount Number of tokens to be increased
*/
function increaseLockAmount(bytes32 _reason, uint256 _amount)
public returns (bool);
/**
* @dev Returns unlockable tokens for a specified address for a specified reason
* @param _of The address to query the the unlockable token count of
* @param _reason The reason to query the unlockable tokens for
*/
function tokensUnlockable(address _of, bytes32 _reason)
public view returns (uint256 amount);
/**
* @dev Unlocks the unlockable tokens of a specified address
* @param _of Address of user, claiming back unlockable tokens
*/
function unlock(address _of)
public returns (uint256 unlockableTokens);
/**
* @dev Gets the unlockable tokens of a specified address
* @param _of The address to query the the unlockable token count of
*/
function getUnlockableTokens(address _of)
public view returns (uint256 unlockableTokens);
}
contract Token is ERC20Interface, Owned, Pausable, ERC1132 {
using SafeMath for uint256;
string public symbol;
string public name;
uint8 public decimals;
uint256 private _totalSupply;
string internal constant ALREADY_LOCKED = 'Tokens already locked';
string internal constant NOT_LOCKED = 'No tokens locked';
string internal constant AMOUNT_ZERO = 'Amount can not be 0';
/* always capped by 10B tokens */
uint256 internal constant MAX_TOTAL_SUPPLY = 10000000000;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) allowed;
mapping(address => uint256) incomes;
mapping(address => uint256) expenses;
mapping(address => bool) frozenAccount;
event FreezeAccount(address _address, bool frozen);
constructor(
uint256 _totalSupply_,
string _name,
string _symbol,
uint8 _decimals)
public
{
symbol = _symbol;
name = _name;
decimals = _decimals;
_totalSupply = _totalSupply_ * 10**uint256(_decimals);
balances[owner] = _totalSupply;
emit Transfer(address(0), owner, _totalSupply);
}
function totalSupply()
public
view
returns (uint256)
{
return _totalSupply;
}
function _transfer(
address _from,
address _to,
uint256 _value)
internal
returns (bool success)
{
require (_to != 0x0);
require (balances[_from] >= _value);
require(!frozenAccount[_from]);
require(!frozenAccount[_to]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
incomes[_to] = incomes[_to].add(_value);
expenses[_from] = expenses[_from].add(_value);
emit Transfer(_from, _to, _value);
return true;
}
function transfer(
address _to,
uint256 _value)
public
whenNotPaused
returns (bool success)
{
return _transfer(msg.sender, _to, _value);
}
function approve(
address _spender,
uint256 _value)
public
whenNotPaused
returns (bool success)
{
require (_spender != 0x0);
require(!frozenAccount[msg.sender]);
require(!frozenAccount[_spender]);
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function transferFrom(
address _from,
address _to,
uint256 _value)
public
whenNotPaused
returns (bool success)
{
require(!frozenAccount[msg.sender]);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
return _transfer(_from, _to, _value);
}
function balanceOf(
address _address)
public
view
returns (uint256 remaining)
{
require(_address != 0x0);
return balances[_address];
}
function incomeOf(
address _address)
public
view
returns (uint256 income)
{
require(_address != 0x0);
return incomes[_address];
}
function expenseOf(
address _address)
public
view
returns (uint256 expense)
{
require(_address != 0x0);
return expenses[_address];
}
function allowance(
address _owner,
address _spender)
public
view
returns (uint256 remaining)
{
require(_owner != 0x0);
require(_spender != 0x0);
return allowed[_owner][_spender];
}
function approveAndCall(
address _spender,
uint256 _value,
bytes _data)
public
whenNotPaused
returns (bool success)
{
if (approve(_spender, _value)) {
require(ApproveAndCallFallBack(_spender).receiveApproval(msg.sender, _value, this, _data) == true);
return true;
}
return false;
}
function freezeAccount(
address _address,
bool freeze)
public
onlyOwner
returns (bool success)
{
frozenAccount[_address] = freeze;
emit FreezeAccount(_address, freeze);
return true;
}
function isFrozenAccount(
address _address)
public
view
returns (bool frozen)
{
require(_address != 0x0);
return frozenAccount[_address];
}
function mint(
uint256 amount)
public
onlyOwner
returns (bool success)
{
uint256 newSupply = _totalSupply + amount;
require(newSupply <= MAX_TOTAL_SUPPLY * 10 **uint256(decimals), "ERC20: exceed maximum total supply");
_totalSupply = newSupply;
balances[owner] += amount;
emit Transfer(address(0), owner, amount);
return true;
}
function burn(
uint256 amount)
public
whenNotPaused
returns (bool success)
{
require (balances[msg.sender] >= amount);
require(!frozenAccount[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(amount);
_totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
return true;
}
function lock(
bytes32 _reason,
uint256 _amount,
uint256 _time)
public
whenNotPaused
returns (bool)
{
uint256 validUntil = now.add(_time); //solhint-disable-line
// If tokens are already locked, then functions extendLock or
// increaseLockAmount should be used to make any changes
require(tokensLocked(msg.sender, _reason) == 0, ALREADY_LOCKED);
require(_amount != 0, AMOUNT_ZERO);
if (locked[msg.sender][_reason].amount == 0)
lockReason[msg.sender].push(_reason);
transfer(address(this), _amount);
locked[msg.sender][_reason] = lockToken(_amount, validUntil, false);
emit Locked(msg.sender, _reason, _amount, validUntil);
return true;
}
function transferWithLock(address _to, bytes32 _reason, uint256 _amount, uint256 _time)
public
whenNotPaused
returns (bool)
{
uint256 validUntil = now.add(_time); //solhint-disable-line
require(tokensLocked(_to, _reason) == 0, ALREADY_LOCKED);
require(_amount != 0, AMOUNT_ZERO);
if (locked[_to][_reason].amount == 0)
lockReason[_to].push(_reason);
transfer(address(this), _amount);
locked[_to][_reason] = lockToken(_amount, validUntil, false);
emit Locked(_to, _reason, _amount, validUntil);
return true;
}
function tokensLocked(address _of, bytes32 _reason)
public
view
returns (uint256 amount)
{
if (!locked[_of][_reason].claimed)
amount = locked[_of][_reason].amount;
}
function tokensLockedAtTime(address _of, bytes32 _reason, uint256 _time)
public
view
returns (uint256 amount)
{
if (locked[_of][_reason].validity > _time)
amount = locked[_of][_reason].amount;
}
function totalBalanceOf(address _of)
public
view
returns (uint256 amount)
{
amount = balanceOf(_of);
for (uint256 i = 0; i < lockReason[_of].length; i++) {
amount = amount.add(tokensLocked(_of, lockReason[_of][i]));
}
}
function extendLock(bytes32 _reason, uint256 _time)
public
whenNotPaused
returns (bool)
{
require(tokensLocked(msg.sender, _reason) > 0, NOT_LOCKED);
locked[msg.sender][_reason].validity = locked[msg.sender][_reason].validity.add(_time);
emit Locked(msg.sender, _reason, locked[msg.sender][_reason].amount, locked[msg.sender][_reason].validity);
return true;
}
function increaseLockAmount(bytes32 _reason, uint256 _amount)
public
whenNotPaused
returns (bool)
{
require(tokensLocked(msg.sender, _reason) > 0, NOT_LOCKED);
transfer(address(this), _amount);
locked[msg.sender][_reason].amount = locked[msg.sender][_reason].amount.add(_amount);
emit Locked(msg.sender, _reason, locked[msg.sender][_reason].amount, locked[msg.sender][_reason].validity);
return true;
}
function tokensUnlockable(address _of, bytes32 _reason)
public
view
returns (uint256 amount)
{
if (locked[_of][_reason].validity <= now && !locked[_of][_reason].claimed) //solhint-disable-line
amount = locked[_of][_reason].amount;
}
function unlock(address _of)
public
whenNotPaused
returns (uint256 unlockableTokens)
{
uint256 lockedTokens;
for (uint256 i = 0; i < lockReason[_of].length; i++) {
lockedTokens = tokensUnlockable(_of, lockReason[_of][i]);
if (lockedTokens > 0) {
unlockableTokens = unlockableTokens.add(lockedTokens);
locked[_of][lockReason[_of][i]].claimed = true;
emit Unlocked(_of, lockReason[_of][i], lockedTokens);
}
}
if (unlockableTokens > 0)
this.transfer(_of, unlockableTokens);
}
function getUnlockableTokens(address _of)
public
view
returns (uint256 unlockableTokens)
{
for (uint256 i = 0; i < lockReason[_of].length; i++) {
unlockableTokens = unlockableTokens.add(tokensUnlockable(_of, lockReason[_of][i]));
}
}
function () public payable {
revert();
}
}
{
"compilationTarget": {
"Token.sol": "Token"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": false,
"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":true,"inputs":[{"name":"_of","type":"address"},{"name":"_reason","type":"bytes32"},{"name":"_time","type":"uint256"}],"name":"tokensLockedAtTime","outputs":[{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isTransferPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","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":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_reason","type":"bytes32"},{"name":"_amount","type":"uint256"},{"name":"_time","type":"uint256"}],"name":"lock","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_of","type":"address"}],"name":"unlock","outputs":[{"name":"unlockableTokens","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"isFrozenAccount","outputs":[{"name":"frozen","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"burn","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_of","type":"address"}],"name":"totalBalanceOf","outputs":[{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_reason","type":"bytes32"},{"name":"_amount","type":"uint256"},{"name":"_time","type":"uint256"}],"name":"transferWithLock","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_of","type":"address"},{"name":"_reason","type":"bytes32"}],"name":"tokensUnlockable","outputs":[{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_of","type":"address"},{"name":"_reason","type":"bytes32"}],"name":"tokensLocked","outputs":[{"name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"balanceOf","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"lockReason","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_reason","type":"bytes32"},{"name":"_amount","type":"uint256"}],"name":"increaseLockAmount","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"viewTransferCount","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"incomeOf","outputs":[{"name":"income","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"mint","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_reason","type":"bytes32"},{"name":"_time","type":"uint256"}],"name":"extendLock","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_of","type":"address"}],"name":"getUnlockableTokens","outputs":[{"name":"unlockableTokens","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"viewOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"bytes32"}],"name":"locked","outputs":[{"name":"amount","type":"uint256"},{"name":"validity","type":"uint256"},{"name":"claimed","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"}],"name":"expenseOf","outputs":[{"name":"expense","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"freeze","type":"bool"}],"name":"freezeAccount","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_totalSupply_","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_address","type":"address"},{"indexed":false,"name":"frozen","type":"bool"}],"name":"FreezeAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_of","type":"address"},{"indexed":true,"name":"_reason","type":"bytes32"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_validity","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_of","type":"address"},{"indexed":true,"name":"_reason","type":"bytes32"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Unlocked","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"}],"name":"TransferOwnership","type":"event"},{"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"}]