_calculateRewards() in PirexGmx don't handle reward calculation properly, and it would revert when totalSupply() is zero which will cause claimRewards() to revert if one of 4 rewardTracker's totalSupply was zero
Audit: 2022-11-redactedcartel-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/PirexGmx.sol#L733-L816
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/PirexGmx.sol#L228-L267
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/PirexRewards.sol#L332-L348


# Vulnerability details

## Impact
Function `claimRewards()` in `PirexGmx` claims WETH and esGMX rewards and multiplier points (MP) from GMX protocol. it uses `_calculateRewards()` to calculate the unclaimed reward token amounts produced for each token type. but because of the lack of checks, function `_calculateRewards()` would revert when `RewardTracker.distributor.totalSupply()` is zero so if any of 4 `RewardTracker`s has zero `totalSupply()` then function `claimRewards()` would revert too and function `harvest()` in `PirexRewards` contract would revert too because it calls `PirexGmx.claimRewards()`. `harvest()` is used in `claim()` function so `claim()` would not work too. This bug would harvesting rewards for `PirexRewards` contract and claiming reward for users from `PirexRewards` when supply of one of `RewardTracker`s contracts in GMX protocol is zero.
Function `claimRewards()` is written based on GMX code, but the logic is not correctly copied because in GMX protocol contract checks for `totalSupply()` and it prevents this bug from happening.

## Proof of Concept
This is function `_calculateRewards()`'s code in `PirexGmx`:
```
   function _calculateRewards(bool isBaseReward, bool useGmx)
        internal
        view
        returns (uint256)
    {
        RewardTracker r;

        if (isBaseReward) {
            r = useGmx ? rewardTrackerGmx : rewardTrackerGlp;
        } else {
            r = useGmx ? stakedGmx : feeStakedGlp;
        }

        address distributor = r.distributor();
        uint256 pendingRewards = IRewardDistributor(distributor)
            .pendingRewards();
        uint256 distributorBalance = (isBaseReward ? gmxBaseReward : esGmx)
            .balanceOf(distributor);
        uint256 blockReward = pendingRewards > distributorBalance
            ? distributorBalance
            : pendingRewards;
        uint256 precision = r.PRECISION();
        uint256 cumulativeRewardPerToken = r.cumulativeRewardPerToken() +
            ((blockReward * precision) / r.totalSupply());

        if (cumulativeRewardPerToken == 0) return 0;

        return
            r.claimableReward(address(this)) +
            ((r.stakedAmounts(address(this)) *
                (cumulativeRewardPerToken -
                    r.previousCumulatedRewardPerToken(address(this)))) /
                precision);
    }
```
As you can see in the line `uint256 cumulativeRewardPerToken = r.cumulativeRewardPerToken() + ((blockReward * precision) / r.totalSupply())` if `totalSupply()` was zero then code would revert because of division by zero error. so if `RewardTracker