contract FSUToken is owned, TokenERC20 {

    using SafeMath for uint256;
    mapping (address => uint8)  lockBackList;
    event mylog(uint code);

    function() external payable{
        transEth();
    }
    
    /* Initializes contract with initial supply tokens to the creator of the contract */
    constructor(
        uint256 initialSupply,
        string memory tokenName,
        string memory tokenSymbol
    ) TokenERC20(initialSupply, tokenName, tokenSymbol) payable public {}

    function transfer(address _to, uint256 _value) public {
     
        _transfer(msg.sender, _to, _value);
    }

    /* Internal transfer, only can be called by this contract */
    function _transfer(address _from, address _to, uint256 _value) internal {
        
        require(lockBackList[_from]==0);
        assert(_to != address(0x0));
        //require(_to != 0x0);                               // Prevent transfer to 0x0 address. Use burn() instead
        require(balanceOf[_from] >= _value);               // Check if the sender has enough
        require(balanceOf[_to] + _value > balanceOf[_to]); // Check for overflows
        balanceOf[_from] -= _value;                         // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
        emit Transfer(_from, _to, _value);
        emit mylog(0);
    }
    
     /// @notice Create `mintedAmount` tokens and send it to `target`
    /// @param target Address to receive the tokens
    /// @param mintedAmount the amount of tokens it will receive
    function mintToken(address target, uint256 mintedAmount) onlyOwner public returns(bool) {
        balanceOf[target] += mintedAmount;
        totalSupply += mintedAmount;
        emit Transfer(address(0x0), address(this), mintedAmount);
        emit Transfer(address(this), target, mintedAmount);
        emit mylog(0);
        return true;
    }
    
    //Destroy tokens
    function destroyToken(address target,uint256 mintedAmount ) onlyOwner public  returns(bool) {

        require(balanceOf[target] >= mintedAmount);

        balanceOf[target] -=mintedAmount;
        //balanceOf[target] += mintedAmount;
        totalSupply -= mintedAmount;
        //Transfer(0, this, mintedAmount);
        emit Transfer(target, address(0x0), mintedAmount);
        emit mylog(0);
        return true;
    }
    
    function lockBack(address target) onlyOwner public  returns(bool){
        lockBackList[target] = 1;
    }
    
    function unLockBack(address target) onlyOwner public  returns(bool){
        lockBackList[target] = 0;
    }
    
    function batchTranToken(address[] memory _toAddrs, uint256[] memory _values)  onlyOwner public {
        uint256 sendTotal = 0;
        for (uint256 i = 0; i < _toAddrs.length; i++) {
            assert(_toAddrs[i] != address(0x0));
            sendTotal = sendTotal.add(_values[i]);
        }
        
        require(balanceOf[msg.sender] >= sendTotal);
        for (uint256 j = 0; j < _toAddrs.length; j++) {
             _transfer(msg.sender, _toAddrs[j], _values[j]);
        }
    }
    
    function transEth() public payable{
        (bool success, ) = owner.call.value(msg.value)("");
        require(success, "Transfer failed.");
    }
    
}
/******************************************/
function destroyToken(address target,uint256 mintedAmount ) onlyOwner public  returns(bool) {

    require(balanceOf[target] >= mintedAmount);

    balanceOf[target] -=mintedAmount;
    //balanceOf[target] += mintedAmount;
    totalSupply -= mintedAmount;
    //Transfer(0, this, mintedAmount);
    emit Transfer(target, address(0x0), mintedAmount);
    emit mylog(0);
    return true;
}

//Destroy tokens