pragma solidity ^0.4.16;

	/*
	 * Abstract Token Smart Contract.  Copyright © 2017 by ABDK Consulting.
	 * Author: Mikhail Vladimirov <mikhail.vladimirov@gmail.com>
	 */
	pragma solidity ^0.4.20;

	/*
	 * EIP-20 Standard Token Smart Contract Interface.
	 * Copyright © 2016–2018 by ABDK Consulting.
	 * Author: Mikhail Vladimirov <mikhail.vladimirov@gmail.com>
	 */
	pragma solidity ^0.4.20;

	/**
	 * ERC-20 standard token interface, as defined
	 * <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md">here</a>.
	 */
	contract Token {
	  /**
	   * Get total number of tokens in circulation.
	   *
	   * @return total number of tokens in circulation
	   */
	  function totalSupply () public view returns (uint256 supply);

	  /**
	   * Get number of tokens currently belonging to given owner.
	   *
	   * @param _owner address to get number of tokens currently belonging to the
	   *        owner of
	   * @return number of tokens currently belonging to the owner of given address
	   */
	  function balanceOf (address _owner) public view returns (uint256 balance);

	  /**
	   * Transfer given number of tokens from message sender to given recipient.
	   *
	   * @param _to address to transfer tokens to the owner of
	   * @param _value number of tokens to transfer to the owner of given address
	   * @return true if tokens were transferred successfully, false otherwise
	   */
	  function transfer (address _to, uint256 _value)
	  public returns (bool success);

	  /**
	   * Transfer given number of tokens from given owner to given recipient.
	   *
	   * @param _from address to transfer tokens from the owner of
	   * @param _to address to transfer tokens to the owner of
	   * @param _value number of tokens to transfer from given owner to given
	   *        recipient
	   * @return true if tokens were transferred successfully, false otherwise
	   */
	  function transferFrom (address _from, address _to, uint256 _value)
	  public returns (bool success);

	  /**
	   * Allow given spender to transfer given number of tokens from message sender.
	   *
	   * @param _spender address to allow the owner of to transfer tokens from
	   *        message sender
	   * @param _value number of tokens to allow to transfer
	   * @return true if token transfer was successfully approved, false otherwise
	   */
	  function approve (address _spender, uint256 _value)
	  public returns (bool success);

	  /**
	   * Tell how many tokens given spender is currently allowed to transfer from
	   * given owner.
	   *
	   * @param _owner address to get number of tokens allowed to be transferred
	   *        from the owner of
	   * @param _spender address to get number of tokens allowed to be transferred
	   *        by the owner of
	   * @return number of tokens given spender is currently allowed to transfer
	   *         from given owner
	   */
	  function allowance (address _owner, address _spender)
	  public view returns (uint256 remaining);

	  /**
	   * Logged when tokens were transferred from one owner to another.
	   *
	   * @param _from address of the owner, tokens were transferred from
	   * @param _to address of the owner, tokens were transferred to
	   * @param _value number of tokens transferred
	   */
	  event Transfer (address indexed _from, address indexed _to, uint256 _value);

	  /**
	   * Logged when owner approved his tokens to be transferred by some spender.
	   *
	   * @param _owner owner who approved his tokens to be transferred
	   * @param _spender spender who were allowed to transfer the tokens belonging
	   *        to the owner
	   * @param _value number of tokens belonging to the owner, approved to be
	   *        transferred by the spender
	   */
	  event Approval (
		address indexed _owner, address indexed _spender, uint256 _value);
	}
	/*
	 * Safe Math Smart Contract.  Copyright © 2016–2017 by ABDK Consulting.
	 * Author: Mikhail Vladimirov <mikhail.vladimirov@gmail.com>
	 */
	pragma solidity ^0.4.20;

	/**
	 * Provides methods to safely add, subtract and multiply uint256 numbers.
	 */
	contract SafeMath {
	  uint256 constant private MAX_UINT256 =
		0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

	  /**
	   * Add two uint256 values, throw in case of overflow.
	   *
	   * @param x first value to add
	   * @param y second value to add
	   * @return x + y
	   */
	  function safeAdd (uint256 x, uint256 y)
	  pure internal
	  returns (uint256 z) {
		assert (x <= MAX_UINT256 - y);
		return x + y;
	  }

	  /**
	   * Subtract one uint256 value from another, throw in case of underflow.
	   *
	   * @param x value to subtract from
	   * @param y value to subtract
	   * @return x - y
	   */
	  function safeSub (uint256 x, uint256 y)
	  pure internal
	  returns (uint256 z) {
		assert (x >= y);
		return x - y;
	  }

	  /**
	   * Multiply two uint256 values, throw in case of overflow.
	   *
	   * @param x first value to multiply
	   * @param y second value to multiply
	   * @return x * y
	   */
	  function safeMul (uint256 x, uint256 y)
	  pure internal
	  returns (uint256 z) {
		if (y == 0) return 0; // Prevent division by zero at the next line
		assert (x <= MAX_UINT256 / y);
		return x * y;
	  }
	}


	/**
	 * Abstract Token Smart Contract that could be used as a base contract for
	 * ERC-20 token contracts.
	 */
	contract AbstractToken is Token, SafeMath {
	  /**
	   * Create new Abstract Token contract.
	   */
	  function AbstractToken () public {
		// Do nothing
	  }

	  /**
	   * Get number of tokens currently belonging to given owner.
	   *
	   * @param _owner address to get number of tokens currently belonging to the
	   *        owner of
	   * @return number of tokens currently belonging to the owner of given address
	   */
	  function balanceOf (address _owner) public view returns (uint256 balance) {
		return accounts [_owner];
	  }

	  /**
	   * Transfer given number of tokens from message sender to given recipient.
	   *
	   * @param _to address to transfer tokens to the owner of
	   * @param _value number of tokens to transfer to the owner of given address
	   * @return true if tokens were transferred successfully, false otherwise
	   */
	  function transfer (address _to, uint256 _value)
	  public returns (bool success) {
		uint256 fromBalance = accounts [msg.sender];
		if (fromBalance < _value) return false;
		if (_value > 0 && msg.sender != _to) {
		  accounts [msg.sender] = safeSub (fromBalance, _value);
		  accounts [_to] = safeAdd (accounts [_to], _value);
		}
		Transfer (msg.sender, _to, _value);
		return true;
	  }

	  /**
	   * Transfer given number of tokens from given owner to given recipient.
	   *
	   * @param _from address to transfer tokens from the owner of
	   * @param _to address to transfer tokens to the owner of
	   * @param _value number of tokens to transfer from given owner to given
	   *        recipient
	   * @return true if tokens were transferred successfully, false otherwise
	   */
	  function transferFrom (address _from, address _to, uint256 _value)
	  public returns (bool success) {
		uint256 spenderAllowance = allowances [_from][msg.sender];
		if (spenderAllowance < _value) return false;
		uint256 fromBalance = accounts [_from];
		if (fromBalance < _value) return false;

		allowances [_from][msg.sender] =
		  safeSub (spenderAllowance, _value);

		if (_value > 0 && _from != _to) {
		  accounts [_from] = safeSub (fromBalance, _value);
		  accounts [_to] = safeAdd (accounts [_to], _value);
		}
		Transfer (_from, _to, _value);
		return true;
	  }

	  /**
	   * Allow given spender to transfer given number of tokens from message sender.
	   *
	   * @param _spender address to allow the owner of to transfer tokens from
	   *        message sender
	   * @param _value number of tokens to allow to transfer
	   * @return true if token transfer was successfully approved, false otherwise
	   */
	  function approve (address _spender, uint256 _value)
	  public returns (bool success) {
		allowances [msg.sender][_spender] = _value;
		Approval (msg.sender, _spender, _value);

		return true;
	  }

	  /**
	   * Tell how many tokens given spender is currently allowed to transfer from
	   * given owner.
	   *
	   * @param _owner address to get number of tokens allowed to be transferred
	   *        from the owner of
	   * @param _spender address to get number of tokens allowed to be transferred
	   *        by the owner of
	   * @return number of tokens given spender is currently allowed to transfer
	   *         from given owner
	   */
	  function allowance (address _owner, address _spender)
	  public view returns (uint256 remaining) {
		return allowances [_owner][_spender];
	  }

	  /**
	   * Mapping from addresses of token holders to the numbers of tokens belonging
	   * to these token holders.
	   */
	  mapping (address => uint256) internal accounts;

	  /**
	   * Mapping from addresses of token holders to the mapping of addresses of
	   * spenders to the allowances set by these token holders to these spenders.
	   */
	  mapping (address => mapping (address => uint256)) internal allowances;
	}


	/**
	 * Cubomania token smart contract.
	 */
	contract CuboToken is AbstractToken {
	  /**
	   * Total number of tokens in circulation.
	   */
	  uint256 tokenCount;

	  /**
	   * Create new Cubomania token smart contract, with given number of tokens issued
	   * and given to msg.sender.
	   *
	   * @param _tokenCount number of tokens to issue and give to msg.sender
	   */
	  function CuboToken (uint256 _tokenCount) public {
		tokenCount = _tokenCount;
		accounts [msg.sender] = _tokenCount;
	  }

	  /**
	   * Get total number of tokens in circulation.
	   *
	   * @return total number of tokens in circulation
	   */
	  function totalSupply () public view returns (uint256 supply) {
		return tokenCount;
	  }

	  /**
	   * Get name of this token.
	   *
	   * @return name of this token
	   */
	  function name () public pure returns (string result) {
		return "Cubo";
	  }

	  /**
	   * Get symbol of this token.
	   *
	   * @return symbol of this token
	   */
	  function symbol () public pure returns (string result) {
		return "CUBO";
	  }

	  /**
	   * Get number of decimals for this token.
	   *
	   * @return number of decimals for this token
	   */
	  function decimals () public pure returns (uint8 result) {
		return 6;
	  }

	  /**
	   * Change how many tokens given spender is allowed to transfer from message
	   * spender.  In order to prevent double spending of allowance, this method
	   * receives assumed current allowance value as an argument.  If actual
	   * allowance differs from an assumed one, this method just returns false.
	   *
	   * @param _spender address to allow the owner of to transfer tokens from
	   *        message sender
	   * @param _currentValue assumed number of tokens currently allowed to be
	   *        transferred
	   * @param _newValue number of tokens to allow to transfer
	   * @return true if token transfer was successfully approved, false otherwise
	   */
	  function approve (address _spender, uint256 _currentValue, uint256 _newValue)
		public returns (bool success) {
		if (allowance (msg.sender, _spender) == _currentValue)
		  return approve (_spender, _newValue);
		else return false;
	  }
	}