Sandwich attack to accruePremiumAndExpireProtections()
Let's show how a malicious user, Bob, can launch a sandwich attack to `accruePremiumAndExpireProtections()` and profit.\\nSuppose there are 1,000,000 underlying tokens for the `ProtectionPool`, and `totalSupply = 1,000,000`, therefore the exchange rate is 1/1 share. Suppose Bob has 100,000 shares.\\nSuppose `accruePremiumAndExpireProtections()` is going to be called and add 100,000 to `totalSTokenUnderlying` at L346.\\nBob front-runs `accruePremiumAndExpireProtections()` and calls `deposit()` to deposit 100,000 underlying tokens into the contract. The check for `ProtectionPoolPhase` will pass for an open phase. As a result, there are 1,100,000 underlying tokens, and 1,100,000 shares, the exchange rate is still 1/1 share. Bob now has 200,000 shares.\\n```\\n function deposit(uint256 _underlyingAmount, address _receiver)\\n    external\\n    override\\n    whenNotPaused\\n    nonReentrant\\n  {\\n    _deposit(_underlyingAmount, _receiver);\\n  }\\n\\n  function _deposit(uint256 _underlyingAmount, address _receiver) internal {\\n    /// Verify that the pool is not in OpenToBuyers phase\\n    if (poolInfo.currentPhase == ProtectionPoolPhase.OpenToBuyers) {\\n      revert ProtectionPoolInOpenToBuyersPhase();\\n    }\\n\\n    uint256 _sTokenShares = convertToSToken(_underlyingAmount);\\n    totalSTokenUnderlying += _underlyingAmount;\\n    _safeMint(_receiver, _sTokenShares);\\n    poolInfo.underlyingToken.safeTransferFrom(\\n      msg.sender,\\n      address(this),\\n      _underlyingAmount\\n    );\\n\\n    /// Verify leverage ratio only when total capital/sTokenUnderlying is higher than minimum capital requirement\\n    if (_hasMinRequiredCapital()) {\\n      /// calculate pool's current leverage ratio considering the new deposit\\n      uint256 _leverageRatio = calculateLeverageRatio();\\n\\n      if (_leverageRatio > poolInfo.params.leverageRatioCeiling) {\\n        revert ProtectionPoolLeverageRatioTooHigh(_leverageRatio);\\n      }\\n    }\\n\\n    emit ProtectionSold(_receiver, _underlyingAmount);\\n }\\n```\\n\\nNow accruePremiumAndExpireProtections()gets called and 100,000 is added to `totalSTokenUnderlying` at L346. As a result, we have 1,200,000 underlying tokens with 1,100,000 shares. The exchange rate becomes 12/11 share.\\nBob calls the `withdraw()` function (assume he made a request two cycles back, he could do that since he had 100,000 underlying tokens in the pool) to withdraw 100,000 shares and he will get `100,000*12/11 = 109,090` underlying tokens. So he has a profit of 9,090 underlying tokens by the sandwich attack.
Create a new contract as a temporary place to store the accrued premium, and then deliver it to the `ProtectionPool` over a period of time (delivery period) with some `premiumPerSecond` to lower the incentive of a quick profit by sandwich attack.\\nRestrict the maximum deposit amount for each cycle.\\nRestrict the maximum withdraw amount for each cycle.
A malicious user can launch a sandwich attack to accruePremiumAndExpireProtections()and profit.
```\\n function deposit(uint256 _underlyingAmount, address _receiver)\\n    external\\n    override\\n    whenNotPaused\\n    nonReentrant\\n  {\\n    _deposit(_underlyingAmount, _receiver);\\n  }\\n\\n  function _deposit(uint256 _underlyingAmount, address _receiver) internal {\\n    /// Verify that the pool is not in OpenToBuyers phase\\n    if (poolInfo.currentPhase == ProtectionPoolPhase.OpenToBuyers) {\\n      revert ProtectionPoolInOpenToBuyersPhase();\\n    }\\n\\n    uint256 _sTokenShares = convertToSToken(_underlyingAmount);\\n    totalSTokenUnderlying += _underlyingAmount;\\n    _safeMint(_receiver, _sTokenShares);\\n    poolInfo.underlyingToken.safeTransferFrom(\\n      msg.sender,\\n      address(this),\\n      _underlyingAmount\\n    );\\n\\n    /// Verify leverage ratio only when total capital/sTokenUnderlying is higher than minimum capital requirement\\n    if (_hasMinRequiredCapital()) {\\n      /// calculate pool's current leverage ratio considering the new deposit\\n      uint256 _leverageRatio = calculateLeverageRatio();\\n\\n      if (_leverageRatio > poolInfo.params.leverageRatioCeiling) {\\n        revert ProtectionPoolLeverageRatioTooHigh(_leverageRatio);\\n      }\\n    }\\n\\n    emit ProtectionSold(_receiver, _underlyingAmount);\\n }\\n```\\n