contract ERC20 is ERC20Basic{
    using SafeMath for uint256;
    
    // Tokens total supply
    uint256 public totalSupply;
	
	// Company's name
	string public name;
	
	// Number of decimals
	uint8 public decimals;
	
	// Token symbol
	string public symbol;
	
	// treasury address
	address treasuryAddress;
	
	// Token version
	string public version;
	
	//Token buyer
	address payable saleAgent;
	
	// Project owner address
	address project_owner;
	
	// Token owner address
	address payable token_owner;
	
	// Balances global values
	mapping (address => uint256) balances;
	
	// Balances with address global values
	mapping (address => mapping (address => uint)) allowed;
	
	// Holder struct
	 struct Holder {
        uint256 payment_id;
        uint256 dateCangeBalance;
    }
        
    // Holder global values
    mapping(address => Holder) holders;
    
	//Fix for short address attack against ERC20
	modifier onlyPayloadSize(uint size) {
		assert(msg.data.length == size + 4);
		_;
	}
	
	// Owner modifier
	 modifier onlyOwner {
        require(msg.sender == project_owner, "ACCESS DENIED");
        _;
    }

    /** @dev Shows balances `_token_owner`.
     * @return amount of tokens owned by `_token_owner`.
     */

	function balanceOf(address _token_owner) public view returns (uint256 amount) {
		return balances[_token_owner];
    }

    /**
     * @dev Moves `tokens` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */

    function transfer(address recipient, uint256 amount) public returns (bool) {
        _transfer(recipient, amount);
        return true;
    }
    
     /**
     * @dev Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
     
	function _transfer(address recipient, uint256 amount) internal  onlyPayloadSize(2*32) {
	    require(recipient != address(0));
	    require(balances[msg.sender] >= amount && amount > 0);
	    balances[msg.sender] = balances[msg.sender].sub(amount);
	    balances[recipient] = balances[recipient].add(amount);
	    holders[recipient].dateCangeBalance = block.timestamp;
	    emit Transfer(msg.sender, recipient, amount);        
    }

    /**
     * @dev Moves `tokens` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    
     
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transferFrom(sender, recipient, amount);
            return true;
    }

     /**
     * @dev Emits an {Transfer} event indicating the updated allowance. 
     * 
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */

    function _transferFrom (address sender, address recipient, uint256 amount) internal {
        require(recipient != address(0) || sender != address (0), "APPROVE TO THE ZERO ADDRESS");
	    require(balances[sender] >= amount && allowed[sender][msg.sender] >= amount && amount > 0);
            balances[recipient] = balances[recipient].add(amount);
            balances[sender] = balances[sender].sub(amount);
            allowed[sender][msg.sender] = allowed[sender][msg.sender].sub(amount);
            holders[recipient].dateCangeBalance = block.timestamp;
            emit Transfer(sender, recipient, amount);
    }

     /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value.
     *
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) public returns (bool) {
        _approve(spender, amount);
        return true;
    }
    /** @dev Sets `tokens` as the allowance of `spender` over the caller's tokens.
     *
     *  boolean value indicating whether the operation succeeded.
     * Emits an {Approval} event.
     */

	function  _approve(address spender, uint256 amount) internal {
        require(spender != address(0), "APPROVE TO THE ZERO ADDRESS");
		allowed[msg.sender][spender] = amount;
		emit Approval(msg.sender, spender, amount);
	}

    /**@dev allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     * @return remaining number of tokens that `spender` will be
     * This value changes when {approve} or {transferFrom} are called.
     */

	function allowance(address _token_owner, address spender) public view returns (uint256 remaining) {
		return allowed[_token_owner][spender];
	}
	
}
function _transferFrom (address sender, address recipient, uint256 amount) internal {
    require(recipient != address(0) || sender != address (0), "APPROVE TO THE ZERO ADDRESS");
 require(balances[sender] >= amount && allowed[sender][msg.sender] >= amount && amount > 0);
        balances[recipient] = balances[recipient].add(amount);
        balances[sender] = balances[sender].sub(amount);
        allowed[sender][msg.sender] = allowed[sender][msg.sender].sub(amount);
        holders[recipient].dateCangeBalance = block.timestamp;
        emit Transfer(sender, recipient, amount);
}

/**
 * @dev Emits an {Transfer} event indicating the updated allowance.
 *
 * Requirements:
 * - `sender` and `recipient` cannot be the zero address.
 * - `sender` must have a balance of at least `amount`.
 * - the caller must have allowance for `sender`'s tokens of at least
 * `amount`.
 */