Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Valid

Protocol DoS due to underflow error in `_updateCreditDelegations`

Summary

Vault::_updateCreditDelegations is susceptible to underflow (0x11) error making the protocol unusable.

Vulnerability Details

For current marketId the old delegated value is cached in UD60x18 previousCreditDelegationUsdX18. Then this value is subtracted from current credit capacity, newCreditDelegationUsdX18. Since the result is expected to be a positive number, UD60x18 creditDeltaUsdX18, the function will revert with a 0x11 underflow panic error when previousCreditDelegationUsdX18 > getTotalCreditCapacityUsd(self).

function _updateCreditDelegations(...) private returns(...) {
...
// cache the previous credit delegation value
@> UD60x18 previousCreditDelegationUsdX18 = ud60x18(creditDelegation.valueUsd);
// cache the latest credit delegation share of the vault's credit capacity
uint128 totalCreditDelegationWeightCache = self.totalCreditDelegationWeight;
if (totalCreditDelegationWeightCache != 0) {
// get the latest credit delegation share of the vault's credit capacity
UD60x18 creditDelegationShareX18 =
ud60x18(creditDelegation.weight).div(ud60x18(totalCreditDelegationWeightCache));
// stores the vault's total credit capacity to be returned
vaultCreditCapacityUsdX18 = getTotalCreditCapacityUsd(self);
// if the vault's credit capacity went to zero or below, we set its credit delegation to that market
// to zero
UD60x18 newCreditDelegationUsdX18 = vaultCreditCapacityUsdX18.gt(SD59x18_ZERO)
? vaultCreditCapacityUsdX18.intoUD60x18().mul(creditDelegationShareX18)
: UD60x18_ZERO;
// calculate the delta applied to the market's total delegated credit
@> UD60x18 creditDeltaUsdX18 = newCreditDelegationUsdX18.sub(previousCreditDelegationUsdX18);
// loads the market's storage pointer and update total delegated credit
Market.Data storage market = Market.load(connectedMarketId);
market.updateTotalDelegatedCredit(creditDeltaUsdX18);

This can happen, for example, when the asset drops in value.

Impact

Protocol DoS.
_updateCreditDelegations is called from all critical contexts, rendering protocol unusable.

Tools Used

Recommendations

In _updateCreditDelegations define creditDeltaUsdX18 as SD59x18 and do the necessary casting

- UD60x18 creditDeltaUsdX18 = newCreditDelegationUsdX18.sub(previousCreditDelegationUsdX18);
+ SD59x18 creditDeltaUsdX18 = newCreditDelegationUsdX18.intoSD59x18().sub(previousCreditDelegationUsdX18.intoSD59x18());

Update Market::updateTotalDelegatedCredit to accept a SD59x18 type to allow the market to decrease its delegated credit.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Vault::_updateCreditDelegations uses unsigned UD60x18 for credit delegation delta calculation which will underflow on any decrease in credit delegation amount

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.