KatanaGovernance::createPair(), Any unauthorized account can create pair with any expired token due to logical error in KatanaGovernance::_isAuthorized() function.
Audit: 2024-10-ronin-findings
Severity: MEDIUM

# Lines of code

https://github.com/ronin-chain/katana-operation-contracts/blob/27f9d28e00958bf3494fa405a8a5acdcd5ecdc5d/src/governance/KatanaGovernance.sol#L375-L381


# Vulnerability details


- **Severity:** Medium
- **Likelihood:** High
- **Description:** Logical error in  `_isAuthorized()` function of Contract KatanaGovernance allowing unauthorized user to create pair with expired tokens(expiry is set by the variable `whitelistUntil`) 

 **Root Cause**: [KatanaGovernance.sol Line 375-381](https://github.com/ronin-chain/katana-operation-contracts/blob/27f9d28e00958bf3494fa405a8a5acdcd5ecdc5d/src/governance/KatanaGovernance.sol#L375-L381)




```solidity
   function _isAuthorized(Permission storage $, address account) private view returns (bool) {
    uint256 expiry = $.whitelistUntil;
    if (expiry == UNAUTHORIZED) return false;
  ->if (expiry == AUTHORIZED || block.timestamp > expiry) return true;

    return $.allowed[account];
  }
  ```
`block.timestamp > expiry` This condition should always return false because if `block.timestamp` is greater than `whitelistUntil` then the corresponding token is already expired and it should not be allowed in any pair.In this case it is returning true and if the the account is not authorized or disallowed then `return $.allowed[account]` statement is not getting a chance to be executed because previous return true statement.

`createPair()` function is external and `isAuthorized(tokens, sender)` is checking if the tokens are authorized to be created as a pair by this specific account.

```solidity
 function createPair(address tokenA, address tokenB) external returns (address pair) {
    address sender = _msgSender();
    address[] memory tokens = new address[](2);
    tokens[0] = tokenA;
    tokens[1] = tokenB;
 --->if (!isAuthorized(tokens, sender)) revert Unauthorized();

    pair = _v2Factory.createPair(tokenA, tokenB);
  }
```
`isAuthorized()` is simply calling `_isAuthorized()`
```solidity
 function isAuthorized(address token, address account) public view returns (bool authorized) {
    if (_isSkipped(account)) return true;

------> authorized = _isAuthorized(_permission[token], account);
  }

  /**
   * @inheritdoc IKatanaGovernance
   */
  function isAuthorized(address[] memory tokens, address account) public view returns (bool authorized) {
    if (_isSkipped(account)) return true;

    uint256 length = tokens.length;
    for (uint256 i; i < length; ++i) {
------>if (!_isAuthorized(_permission[tokens[i]], account)) return false;
    }

    return true;
  }
```
- **Impact:** Impact is High. Malicious user who is blocked or disallowed to create pair is able to create pair with expired tokens and can manipulate the system to get advantage from the protocol.It is severely impacting the protocols integrity and creates unintended consequences.
- **Recommendation:** 

  
 
  ```solidity
  function _isAuthorized(Permission storage $, address account) private view returns (bool) {
    uint256 expiry = $.w