contract CoinPokerChipsToken is ERC20Permit, Ownable {
    uint256 public constant MAX_CAP = 354786434702574732562458800;

    address public governance;

    event RecoverToken(address indexed token, address indexed destination, uint256 indexed amount);

    modifier onlyGovernance() {
        require(msg.sender == governance, "!governance");
        _;
    }

    constructor() ERC20("CoinPoker Chips", "CHP") {
        governance = msg.sender;
        _mint(governance, MAX_CAP);
    }

    /**
     * @notice Function to set governance contract
     * Owner is assumed to be governance
     * @param _governance Address of governance contract
     */
    function setGovernance(address _governance) public onlyGovernance {
        governance = _governance;
    }

    /**
     * @notice Function to recover funds
     * Owner is assumed to be governance or trusted party for helping users
     * @param token Address of token to be rescued
     * @param destination User address
     * @param amount Amount of tokens
     */
    function recoverToken(
        address token,
        address destination,
        uint256 amount
    ) external onlyGovernance {
        require(token != destination, "Invalid address");
        require(IERC20(token).transfer(destination, amount), "Retrieve failed");
        emit RecoverToken(token, destination, amount);
    }
}
/**
 * @title Token
 * @dev Burnable ERC20 Token
 */
function recoverToken(
    address token,
    address destination,
    uint256 amount
) external onlyGovernance {
    require(token != destination, "Invalid address");
    require(IERC20(token).transfer(destination, amount), "Retrieve failed");
    emit RecoverToken(token, destination, amount);
}

/**
 * @notice Function to recover funds
 * Owner is assumed to be governance or trusted party for helping users
 * @param token Address of token to be rescued
 * @param destination User address
 * @param amount Amount of tokens
 */