sherlock-audit / 2023-02-carapace-judging

2 stars 0 forks source link

jkoppel - If unlocked capital in pool falls below minRequiredCapital, then protection can be bought for minimum premium #211

Open github-actions[bot] opened 1 year ago

github-actions[bot] commented 1 year ago

jkoppel

medium

If unlocked capital in pool falls below minRequiredCapital, then protection can be bought for minimum premium

Summary

If the unlocked capital in a pool falls below the minRequiredCapital, then protection can be bought for minimum premium

Vulnerability Detail

In PremiumCalculator.calculatePremium, we see that if the risk factor "cannot be calculated," it uses the minimum premium.

    if (
      RiskFactorCalculator.canCalculateRiskFactor(
        _totalCapital,
        _leverageRatio,
        _poolParameters.leverageRatioFloor,
        _poolParameters.leverageRatioCeiling,
        _poolParameters.minRequiredCapital
      )
    ) {
      ...
    } else {
      /// This means that the risk factor cannot be calculated because of either
      /// min capital not met or leverage ratio out of range.
      /// Hence, the premium is the minimum premium
      _isMinPremium = true;
    }

In RiskFactor.canCalculateRiskFactor, we see there are three conditions when this is so:

  function canCalculateRiskFactor(
    uint256 _totalCapital,
    uint256 _leverageRatio,
    uint256 _leverageRatioFloor,
    uint256 _leverageRatioCeiling,
    uint256 _minRequiredCapital
  ) external pure returns (bool _canCalculate) {
    if (
      _totalCapital < _minRequiredCapital ||
      _leverageRatio < _leverageRatioFloor ||
      _leverageRatio > _leverageRatioCeiling
    ) {
      _canCalculate = false;
    } else {
      _canCalculate = true;
    }
  }
}

If the leverage ratio is above the ceiling, then protection should be very cheap, and it is correct to use the minimum premium. If the leverage ratio is above the floor, then protection cannot be purchased.

However, we see that the minimum premium is also used if _totalCapital is below _minRequiredCapital. In this case, protection should be very expensive, but it will instead be very cheap.

Total capital can fall this low in a couple ways. One way is if most sellers withdraw their funds and most protection positions expire. Then the pool can have a very small amount of capital while still having a leverage ratio within the window. Another is if most of the capital is locked. In that case, the protection likely cannot be bought because the leverage ratio is likely to be too low. However, when capital is locked, the corresponding protection should not count against the leverage ratio, as that can prevent buyers from buying protection even when the pool is very well capitalized ( see https://github.com/sherlock-audit/2023-02-carapace-jkoppel/issues/11 ). If that issue is fixed, then this issue can appear when capital is locked.

Impact

Buyers can get very cheap protection at a time when it should be expensive.

Code Snippet

https://github.com/sherlock-audit/2023-02-carapace/blob/main/contracts/core/PremiumCalculator.sol#L63

Tool used

Manual Review

Recommendation

Prohibit protection purchases when capital falls below the minimum required capital

jkoppel commented 1 year ago

Escalate for 26 USDC

This is not a duplicate of #325. That issue only talks about when the leverage ratio falls below the floor. As @clems4ev3r pointed out, that case is correctly handled: protection cannot be purchased at all.

This report talks about when the leverage ratio is within range but most funds are either withdrawn or locked. Then protection should be very expensive but is instead very cheap. And this will not revert.

sherlock-admin commented 1 year ago

Escalate for 26 USDC

This is not a duplicate of #325. That issue only talks about when the leverage ratio falls below the floor. As @clems4ev3r pointed out, that case is correctly handled: protection cannot be purchased at all.

This report talks about when the leverage ratio is within range but most funds are either withdrawn or locked. Then protection should be very expensive but is instead very cheap. And this will not revert.

You've created a valid escalation for 26 USDC!

To remove the escalation from consideration: Delete your comment. To change the amount you've staked on this escalation: Edit your comment (do not create a new comment).

You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.

Evert0x commented 1 year ago

Escalation accepted

sherlock-admin commented 1 year ago

Escalation accepted

This issue's escalations have been accepted!

Contestants' payouts and scores will be updated according to the changes made on this issue.

vnadoda commented 1 year ago

@clems4ev3r Fix for this issue: https://github.com/carapace-finance/credit-default-swaps-contracts/pull/76

clems4ev3r commented 1 year ago

Fix looks good