redeem() should be possible when protocol is Paused but to be able to redeem function grantRTokenAllowance() should be called for any basket tokens and it can only be called when protocol is not paused
Audit: 2023-01-reserve-findings
Severity: MEDIUM

# Lines of code

https://github.com/reserve-protocol/protocol/blob/df7ecadc2bae74244ace5e8b39e94bc992903158/contracts/p1/BackingManager.sol#L67-L77
https://github.com/reserve-protocol/protocol/blob/df7ecadc2bae74244ace5e8b39e94bc992903158/contracts/p1/RToken.sol#L439-L443


# Vulnerability details

## Impact
Function `redeem()` in RToken contract, redeems RToken for basket collateral and it's callable when protocol is paused. but function `redeem()` transfers basket tokens from BackingManager contract to redeemer and it requires spending allowance of the BackingManger tokens which is granted by calling `grantRTokenAllowance()` for each basket tokens. function `grantRTokenAllowance()` is not callable when protocol is paused. so if for any one of the basket tokens function `grantRTokenAllowance()` didn't get called (newly added tokens to basket) then when protocol is paused `grantRTokenAllowance()` can't be called and `redeem()` won't be possible.

## Proof of Concept
This is `grantRTokenAllowance()` code:
```
    function grantRTokenAllowance(IERC20 erc20) external notPausedOrFrozen {
        require(assetRegistry.isRegistered(erc20), "erc20 unregistered");
        // == Interaction ==
        IERC20Upgradeable(address(erc20)).safeApprove(address(main.rToken()), 0);
        IERC20Upgradeable(address(erc20)).safeApprove(address(main.rToken()), type(uint256).max);
    }
```
As you can see it gives RToken spending allowance and it can't be called when protocol is Paused.
This is `redeem()` code:
```
function redeem(uint256 amount) external notFrozen {
        require(amount > 0, "Cannot redeem zero");
.........
.........
.........
        // Accept and burn RToken, reverts if not enough balance to burn
        _burn(redeemer, amount);

        bool allZero = true;
        for (uint256 i = 0; i < erc20length; ++i) {
            if (amounts[i] == 0) continue;
            if (allZero) allZero = false;

            // Send withdrawal
            IERC20Upgradeable(erc20s[i]).safeTransferFrom(
                address(backingManager),
                redeemer,
                amounts[i]
            );
        }

        if (allZero) revert("Empty redemption");
    }
```
As you can see it can be called when protocol is paused and it transfers tokens from BackingManager to redeemer and require that RToken has spending allowance of BackingManager tokens so function `grantRTokenAllowance()` most be called for basket tokens before.
the problem is that if there were newly added token in the basket and `grantRTokenAllowance()` isn't called for that token and protocol was paused then user won't be able to `redeem()` because `grantRTokenAllowance()` is not callable during Paused time and `redeem()` won't be possible in Paused time. so as docs says that `redeem()` should be possible when protocol is paused but it won't happen in all cases and redeem() would be blocked.

## Tools Used
VIM

## Recommended Mitigation Steps
allow `grantRTokenAllowance()` to be called whe