contract ToshiCash is Ownable, MinterRole, CanTransferRole {
    using SafeMath for uint256;

    event Transfer(address indexed from, address indexed to, uint256 value);

    mapping(address => uint256) private _balances;

    string public name = "ToshiCash";
    string public symbol = "ToshiCash";
    uint8 public decimals = 18;

    uint256 public totalSupply;
    uint256 public totalClaimed;
    uint256 public totalMinted;



    constructor() public {

    }

    function addClaimed(uint256 amount) internal {
        totalClaimed = totalClaimed.add(amount);
    }

    function addMinted(uint256 amount) internal {
        totalMinted = totalMinted.add(amount);
    }

    /**
     * @dev Claiming is white-listed to specific minter addresses for now to limit transfers.
     */
    function claim(address to, uint256 amount) public onlyCanTransfer {
        transfer(to, amount);
        addClaimed(amount);
    }

    /**
     * @dev Transferring is white-listed to specific minter addresses for now.
     */
    function transfer(address to, uint256 amount)
        public
        returns (bool)
    {
        require(
            amount <= _balances[msg.sender],
            "ToshiCash: Cannot transfer more than balance"
        );

        _balances[msg.sender] = _balances[msg.sender].sub(amount);
        _balances[to] = _balances[to].add(amount);

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    /**
     * @dev Transferring is white-listed to specific minter addresses for now.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public onlyCanTransfer returns (bool) {
        require(
            amount <= _balances[from],
            "ToshiCash: Cannot transfer more than balance"
        );

        _balances[from] = _balances[from].sub(amount);
        _balances[to] = _balances[to].add(amount);

        emit Transfer(from, to, amount);

        return true;
    }

    /**
     * @dev Gets the balance of the specified address.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev Minting is white-listed to specific minter addresses for now.
     */
    function mint(address to, uint256 amount) public onlyMinter {
        _mint(to, amount);
        addMinted(amount);
    }

    /**
     * @dev Burning is white-listed to specific minter addresses for now.
     */
    function burn(address from, uint256 value) public onlyCanTransfer {
        require(
            _balances[from] >= value,
            "ToshiCash: Cannot burn more than the address balance"
        );

        _burn(from, value);
    }

    /**
     * @dev Internal function that creates an amount of the token and assigns it to an account.
     * This encapsulates the modification of balances such that the proper events are emitted.
     * @param to The account that will receive the created tokens.
     * @param amount The amount that will be created.
     */
    function _mint(address to, uint256 amount) internal {
        require(to != address(0), "ToshiCash: mint to the zero address");

        totalSupply = totalSupply.add(amount);
        _balances[to] = _balances[to].add(amount);

        emit Transfer(address(0), to, amount);
    }

    /**
     * @dev Internal function that destroys an amount of the token of a given address.
     * @param from The account whose tokens will be destroyed.
     * @param amount The amount that will be destroyed.
     */
    function _burn(address from, uint256 amount) internal {
        require(from != address(0), "ToshiCash: burn from the zero address");

        totalSupply = totalSupply.sub(amount);
        _balances[from] = _balances[from].sub(amount);

        emit Transfer(from, address(0), amount);
    }


}
function mint(address to, uint256 amount) public onlyMinter {
    _mint(to, amount);
    addMinted(amount);
}

/**
 * @dev Minting is white-listed to specific minter addresses for now.
 */