Using a cached price in the critical shutdownMarket()
The `MarketShutdownFacet::shutdownMarket()` is a critical function allowing anyone to freeze the market permanently. The function determines whether or not the market will be frozen based on the asset collateral ratio calculated from a cached price, which can be outdated (too risky for this critical function).\\nOnce the market is frozen, no one can unfreeze it.\\nThe `shutdownMarket()` allows anyone to call to freeze the market permanently when the asset collateral ratio threshold (default of 1.1 ether) has been reached. Once the market is frozen, all shorters will lose access to their positions. Even the protocol's DAO or admin cannot unfreeze the market. Therefore, the `shutdownMarket()` becomes one of the most critical functions.\\nTo calculate the asset collateral ratio (cRatio), the `shutdownMarket()` executes the `_getAssetCollateralRatio()`. However, the `_getAssetCollateralRatio()` calculates the `cRatio` using the cached price loaded from the `LibOracle::getPrice()`.\\nUsing the cached price in a critical function like `shutdownMarket()` is too risky, as the cached price can be outdated. The function should consider only a fresh price queried from Chainlink.\\n```\\n    function shutdownMarket(address asset)\\n        external\\n        onlyValidAsset(asset)\\n        isNotFrozen(asset)\\n        nonReentrant\\n    {\\n      uint256 cRatio = _getAssetCollateralRatio(asset);\\n      if (cRatio > LibAsset.minimumCR(asset)) {\\n            revert Errors.SufficientCollateral();\\n        } else {\\n            STypes.Asset storage Asset = s.asset[asset];\\n            uint256 vault = Asset.vault;\\n            uint88 assetZethCollateral = Asset.zethCollateral;\\n            s.vault[vault].zethCollateral -= assetZethCollateral;\\n          Asset.frozen = F.Permanent;\\n            if (cRatio > 1 ether) {\\n                // More than enough collateral to redeem ERC 1:1, send extras to TAPP\\n                uint88 excessZeth =\\n                    assetZethCollateral - assetZethCollateral.divU88(cRatio);\\n                s.vaultUser[vault][address(this)].ethEscrowed += excessZeth;\\n                // Reduces c-ratio to 1\\n                Asset.zethCollateral -= excessZeth;\\n            }\\n        }\\n        emit Events.ShutdownMarket(asset);\\n    }\\n\\n    // rest of code\\n\\n    function _getAssetCollateralRatio(address asset)\\n        private\\n        view\\n        returns (uint256 cRatio)\\n    {\\n        STypes.Asset storage Asset = s.asset[asset];\\n      return Asset.zethCollateral.div(LibOracle.getPrice(asset).mul(Asset.ercDebt));\\n    }\\n```\\n\\nhttps://github.com/Cyfrin/2023-09-ditto/blob/a93b4276420a092913f43169a353a6198d3c21b9/contracts/facets/MarketShutdownFacet.sol#L36\\nhttps://github.com/Cyfrin/2023-09-ditto/blob/a93b4276420a092913f43169a353a6198d3c21b9/contracts/facets/MarketShutdownFacet.sol#L37\\nhttps://github.com/Cyfrin/2023-09-ditto/blob/a93b4276420a092913f43169a353a6198d3c21b9/contracts/facets/MarketShutdownFacet.sol#L44\\nhttps://github.com/Cyfrin/2023-09-ditto/blob/a93b4276420a092913f43169a353a6198d3c21b9/contracts/facets/MarketShutdownFacet.sol#L99
Using a cached price in the critical shutdownMarket()\\nThe `shutdownMarket()` requires the most accurate price, not just a cached price. Execute the `LibOracle::getOraclePrice()` to get the accurate price from Chainlink.
Using the cached price in a critical function like `shutdownMarket()` is too risky, as the cached price can be outdated.\\nOnce the market is frozen, all shorters will lose access to their positions. Even the protocol's DAO or admin cannot unfreeze the market.
```\\n    function shutdownMarket(address asset)\\n        external\\n        onlyValidAsset(asset)\\n        isNotFrozen(asset)\\n        nonReentrant\\n    {\\n      uint256 cRatio = _getAssetCollateralRatio(asset);\\n      if (cRatio > LibAsset.minimumCR(asset)) {\\n            revert Errors.SufficientCollateral();\\n        } else {\\n            STypes.Asset storage Asset = s.asset[asset];\\n            uint256 vault = Asset.vault;\\n            uint88 assetZethCollateral = Asset.zethCollateral;\\n            s.vault[vault].zethCollateral -= assetZethCollateral;\\n          Asset.frozen = F.Permanent;\\n            if (cRatio > 1 ether) {\\n                // More than enough collateral to redeem ERC 1:1, send extras to TAPP\\n                uint88 excessZeth =\\n                    assetZethCollateral - assetZethCollateral.divU88(cRatio);\\n                s.vaultUser[vault][address(this)].ethEscrowed += excessZeth;\\n                // Reduces c-ratio to 1\\n                Asset.zethCollateral -= excessZeth;\\n            }\\n        }\\n        emit Events.ShutdownMarket(asset);\\n    }\\n\\n    // rest of code\\n\\n    function _getAssetCollateralRatio(address asset)\\n        private\\n        view\\n        returns (uint256 cRatio)\\n    {\\n        STypes.Asset storage Asset = s.asset[asset];\\n      return Asset.zethCollateral.div(LibOracle.getPrice(asset).mul(Asset.ercDebt));\\n    }\\n```\\n