MEDIUM severity: Vulnerable function: ```\n    function rate() external view returns (uint256) {\n        uint256 safeEarnerRate_ = getSaf. ```\n    function rate() external view returns (uint256) {\n        uint256 safeEarnerRate_ = getSafeEarnerRate(\n            IMinterGateway(minterGateway).totalActiveOwedM(),\n            IMToken(mToken).totalEarningSupply(),\n            IMinterGateway(minterGateway).minterRate()\n        );\n\n  

Vulnerable code:
```\n    function rate() external view returns (uint256) {\n        uint256 safeEarnerRate_ = getSafeEarnerRate(\n            IMinterGateway(minterGateway).totalActiveOwedM(),\n            IMToken(mToken).totalEarningSupply(),\n            IMinterGateway(minterGateway).minterRate()\n        );\n\n        return UIntMath.min256(maxRate(), (RATE_MULTIPLIER * safeEarnerRate_) / ONE);\n    }\n\n    function getSafeEarnerRate(\n        uint240 totalActiveOwedM_,\n        uint240 totalEarningSupply_,\n        uint32 minterRate_\n    ) public pure returns (uint32) {\n        // solhint-disable max-line-length\n        // When `totalActiveOwedM_ >= totalEarningSupply_`, it is possible for the earner rate to be higher than the\n        // minter rate and still ensure cashflow safety over some period of time (`RATE_CONFIDENCE_INTERVAL`). To ensure\n        // cashflow safety, we start with `cashFlowOfActiveOwedM >= cashFlowOfEarningSupply` over some time `dt`.\n        // Effectively: p1 * (exp(rate1 * dt) - 1) >= p2 * (exp(rate2 * dt) - 1)\n        //          So: rate2 <= ln(1 + (p1 * (exp(rate1 * dt) - 1)) / p2) / dt\n        // 1. totalActive * (delta_minterIndex - 1) >= totalEarning * (delta_earnerIndex - 1)\n        // 2. totalActive * (delta_minterIndex - 1) / totalEarning >= delta_earnerIndex - 1\n        // 3. 1 + (totalActive * (delta_minterIndex - 1) / totalEarning) >= delta_earnerIndex\n        // Substitute `delta_earnerIndex` with `exponent((earnerRate * dt) / SECONDS_PER_YEAR)`:\n        // 4. 1 + (totalActive * (delta_minterIndex - 1) / totalEarning) >= exponent((earnerRate * dt) / SECONDS_PER_YEAR)\n        // 5. ln(1 + (totalActive * (delta_minterIndex - 1) / totalEarning)) >= (earnerRate * dt) / SECONDS_PER_YEAR\n        // 6. ln(1 + (totalActive * (delta_minterIndex - 1) / totalEarning)) * SECONDS_PER_YEAR / dt >= earnerRate\n\n        // When `totalActiveOwedM_ < totalEarningSupply_`, the instantaneous earner cash flow must be less than the\n        // instantaneous minter cash flow. To ensure instantaneous cashflow safety, we we use the derivatives of the\n        // previous starting inequality, and substitute `dt = 0`.\n        // Effectively: p1 * rate1 >= p2 * rate2\n        //          So: rate2 <= p1 * rate1 / p2\n        // 1. totalActive * minterRate >= totalEarning * earnerRate\n        // 2. totalActive * minterRate / totalEarning >= earnerRate\n        // solhint-enable max-line-length\n\n        if (totalActiveOwedM_ == 0) return 0;\n\n        if (totalEarningSupply_ == 0) return type(uint32).max;\n\n        if (totalActiveOwedM_ <= totalEarningSupply_) {//@audit-info rate is slashed\n            // NOTE: `totalActiveOwedM_ * minterRate_` can revert due to overflow, so in some distant future, a new\n            //       rate model contract may be needed that handles this differently.\n            return uint32((uint256(totalActiveOwedM_) * minterRate_) / totalEarningSupply_);\n        }\n\n        uint48 deltaMinterIndex_ = ContinuousIndexingMath.getContinuousIndex(\n            ContinuousIndexingMath.convertFromBasisPoints(minterRate_),\n            RATE_CONFIDENCE_INTERVAL\n        );//@audit-info deltaMinterIndex for 30 days\n\n        // NOTE: `totalActiveOwedM_ * deltaMinterIndex_` can revert due to overflow, so in some distant future, a new\n        //       rate model contract may be needed that handles this differently.\n        int256 lnArg_ = int256(\n            _EXP_SCALED_ONE +\n                ((uint256(totalActiveOwedM_) * (deltaMinterIndex_ - _EXP_SCALED_ONE)) / totalEarningSupply_)\n        );\n\n        int256 lnResult_ = wadLn(lnArg_ * _WAD_TO_EXP_SCALER) / _WAD_TO_EXP_SCALER;\n\n        uint256 expRate_ = (uint256(lnResult_) * ContinuousIndexingMath.SECONDS_PER_YEAR) / RATE_CONFIDENCE_INTERVAL;\n\n        if (expRate_ > type(uint64).max) return type(uint32).max;\n\n        // NOTE: Do not need to do `UIntMath.safe256` because it is known that `lnResult_` will not be negative.\n        uint40 safeRate_ = ContinuousIndexingMath.convertToBasisPoints(uint64(expRate_));\n\n        return (safeRate_ > type(uint32).max) ? type(uint32).max : uint32(safeRate_);\n    }\n```\n