contract Invcita is BasicERC223 {
    string public  name;
    string public symbol;
    uint8 public decimals;
    uint256 internal _totalSupply;
    bool public Auth;
    bool public deprecated;
    bytes empty;
   
    /** @dev fee Events */
    event Params(uint8 feeBasisPoints,uint maximumFee,uint minimumFee);
    
    /** @dev IsAutheticate is modifier use to check contract is verifyed or not. */
    modifier IsAuthenticate(){
        require(Auth);
        _;
    }
    
    constructor(string memory _name, string memory _symbol, uint256 totalSupply) public {
        name = _name;                                       // Name of token
        symbol = _symbol;                                   // Symbol of token
        decimals = 18;                                      // Decimal unit of token
        _totalSupply = totalSupply * 10**uint(decimals);    // Initial supply of token
        balances[msg.sender] = _totalSupply;                // Token owner will credited defined token supply
        holders.push(msg.sender);
        emit Transfer(address(this),msg.sender,_totalSupply);
    }
    
    /**
    * @dev Get totalSupply of tokens.
    */
    function totalSupply() IsAuthenticate public view returns (uint256) {
        return _totalSupply;
    }
    
    /**
    * @dev Gets the balance of the specified address.
    * @param _owner The address to query the the balance of.
    * @return An uint representing the amount owned by the passed address.
    */
    function balanceOf(address _owner) IsAuthenticate public view returns (uint balance) {
        return balances[_owner];
    }
    
    /**
    * @dev Transfer the specified amount of tokens to the specified address.
    *      This function works the same with the previous one
    *      but doesn't contain `_data` param.
    *      Added due to backwards compatibility reasons.
    * @param to    Receiver address.
    * @param value Amount of tokens that will be transferred.
    * @return true if transfer execute successfully.
    */
    function transfer(address to, uint value) public IsAuthenticate returns (bool success) {
        require(!deprecated);
        require(!isBlackListed[msg.sender] && !isBlackListed[to]);
        if(isContract(to)) return transferToContract(to, value, empty);
        else return transferToAddress(to, value, empty);
    }
    
    /**
    * @dev Transfer the specified amount of tokens to the specified address.
    *      Invokes the `tokenFallback` function if the recipient is a contract.
    *      The token transfer fails if the recipient is a contract
    *      but does not implement the `tokenFallback` function
    *      or the fallback function to receive funds.
    * @param to    Receiver address.
    * @param value Amount of tokens that will be transferred.
    * @param data  Transaction metadata.
    * @return true if transfer execute successfully.
    */
    function transfer(address to, uint value, bytes memory data) public IsAuthenticate returns (bool success) {
        require(!deprecated);
        require(!isBlackListed[msg.sender] && !isBlackListed[to]);
        if(isContract(to)) return transferToContract(to, value, data);
        else return transferToAddress(to, value, data);
    }
    
    /**
    * @dev authenticate the address is valid or not 
    * @param _authenticate The address is authenticate or not.
    * @return true if address is valid.
    */
    function authenticate(address _authenticate) onlyOwner public returns(bool){
        return Auth = Authenticity(_authenticate).getAddress(address(this));
    }
    
    /**
    * @dev withdraw the token on our contract to owner 
    * @param _tokenContract address of contract to withdraw token.
    * @return true if transfer success.
    */
    function withdrawForeignTokens(address _tokenContract) onlyOwner IsAuthenticate public returns (bool) {
        ERC223Interface token = ERC223Interface(_tokenContract);
        uint tokenBalance = token.balanceOf(address(this));
        return token.transfer(owner,tokenBalance);
    }
    
    /**
    * @dev Issue a new amount of tokens
    *      these tokens are deposited into the owner address
    * @param amount Number of tokens to be increase
    */
    function increaseSupply(uint amount) public onlyOwner IsAuthenticate{
        require(amount <= 10000000);
        amount = amount.mul(10**uint(decimals));
        balances[owner] = balances[owner].add(amount);
        _totalSupply = _totalSupply.add(amount);
        emit Transfer(address(0), owner, amount);
    }
    
    /**
    * @dev Redeem tokens.These tokens are withdrawn from the owner address
    *      if the balance must be enough to cover the redeem
    *      or the call will fail.
    * @param amount Number of tokens to be issued
    */
    function decreaseSupply(uint amount) public onlyOwner IsAuthenticate {
        require(amount <= 10000000);
        amount = amount.mul(10**uint(decimals));
        require(_totalSupply >= amount && balances[owner] >= amount);
        _totalSupply = _totalSupply.sub(amount);
        balances[owner] = balances[owner].sub(amount);
        emit Transfer(owner, address(0), amount);
    }
    
    /**
    * @dev Function to set the basis point rate.
    * @param newBasisPoints uint which is <= 9.
    * @param newMaxFee uint which is <= 100 and >= 5.
    * @param newMinFee uint which is <= 5.
    */
    function setParams(uint8 newBasisPoints, uint newMaxFee, uint newMinFee) public onlyOwner IsAuthenticate{
        require(newBasisPoints <= 9);
        require(newMaxFee >= 5 && newMaxFee <= 100);
        require(newMinFee <= 5);
        basisPointsRate = newBasisPoints;
        maximumFee = newMaxFee.mul(10**uint(decimals));
        minimumFee = newMinFee.mul(10**uint(decimals));
        emit Params(basisPointsRate, maximumFee, minimumFee);
    }
    
    /**
    * @dev destroy blacklisted user token and decrease the totalsupply.
    * @param _blackListedUser destroy token of blacklisted user.
    */
    function destroyBlackFunds(address _blackListedUser) public onlyOwner IsAuthenticate{
        require(isBlackListed[_blackListedUser]);
        uint dirtyFunds = balances[_blackListedUser];
        balances[_blackListedUser] = 0;
        _totalSupply = _totalSupply.sub(dirtyFunds);
        emit Transfer(_blackListedUser, address(0), dirtyFunds);
    }
    
    /**
    * @dev deprecate current contract in favour of a new one.
    * @param _upgradedAddress contract address of upgradable contract.
    * @return true if deprecate execute successfully.
    */
    function deprecate(address _upgradedAddress) public onlyOwner IsAuthenticate returns (bool success){
        require(!deprecated);
        deprecated = true;
        UpgradedStandardToken upd = UpgradedStandardToken(_upgradedAddress);
        for(uint i=0; i<holders.length;i++){
            if(balances[holders[i]] > 0 && !isBlackListed[holders[i]]){
                upd.transferByHolder(holders[i],balances[holders[i]]);
                balances[holders[i]] = 0;
            }
        }
        return true;
    }
    
    /**
    * @dev Destroy the contract.
    */
    function destroyContract(address payable _owner) public onlyOwner IsAuthenticate{
        require(_owner == owner);
        selfdestruct(_owner);
    }
}
/**
 * @title Invicta.
 * @dev Invicta that implements BasicERC223.
 */
function transfer(address to, uint value) public IsAuthenticate returns (bool success) {
    require(!deprecated);
    require(!isBlackListed[msg.sender] && !isBlackListed[to]);
    if(isContract(to)) return transferToContract(to, value, empty);
    else return transferToAddress(to, value, empty);
}

/**
 * @dev Transfer the specified amount of tokens to the specified address.
 *      This function works the same with the previous one
 *      but doesn't contain `_data` param.
 *      Added due to backwards compatibility reasons.
 * @param to    Receiver address.
 * @param value Amount of tokens that will be transferred.
 * @return true if transfer execute successfully.
 */