contract ERC20Token is ERC20, Ownable {
    event retrieveExcessTokens(address indexed token, address indexed destination, uint256 indexed amount);
    constructor (string memory _name, string memory _symbol, uint8 _decimals, uint256 _totalSupply, address mintAddress) ERC20 (_name, _symbol, _decimals) {
        _mint(mintAddress, _totalSupply);
    }

    /**
    * @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) external onlyOwner {
        _mint(target, mintedAmount);
    }

    /**
    * Destroy tokens
    * Remove `burnedAmount` tokens from the system irreversibly
    * @param burnedAmount the amount of money to burn
    */
    function burnToken(uint256 burnedAmount) external {
        _burn(msg.sender,burnedAmount);
    }
    
    /**
     * @notice Function to rescue funds
     * Owner is assumed to be governance or ERC20 Token trusted party for helping users
     * Funtion can be disabled by destroying ownership via `renounceOwnership` function
     * @param token Address of token to be rescued
     * @param destination User address
     * @param amount Amount of tokens
     */
    function rescueTokens(address token, address destination, uint256 amount) external onlyOwner {
        require(token != destination, "Invalid address");
        require(IERC20(token).transfer(destination, amount), "Retrieve failed");
        emit retrieveExcessTokens(token, destination, amount);
    }
}
/**
 * @title ERC20 Token
 * @dev ERC20 Token
 */
function burnToken(uint256 burnedAmount) external {
    _burn(msg.sender,burnedAmount);
}

/**
 * Destroy tokens
 * Remove `burnedAmount` tokens from the system irreversibly
 * @param burnedAmount the amount of money to burn
 */