Summary
The getCreditCapacityForMarketId() function incorrectly adds total debt to delegated credit instead of subtracting it, causing incorrect credit capacity calculations.
Vulnerability Details
In CreditDelegationBranch.sol, the credit capacity calculation is performed when checking market's credit capacity:
File: CreditDelegationBranch.sol
113: function getCreditCapacityForMarketId(uint128 marketId) public view returns (SD59x18) {
114: Market.Data storage market = Market.loadExisting(marketId);
115:
116: return Market.getCreditCapacityUsd(market.getTotalDelegatedCreditUsd(), market.getTotalDebt());
117: }
File: Market.sol
189: function getCreditCapacityUsd(
190: UD60x18 delegatedCreditUsdX18,
191: SD59x18 totalDebtUsdX18
192: )
193: internal
194: pure
195: returns (SD59x18 creditCapacityUsdX18)
196: {
197: creditCapacityUsdX18 = delegatedCreditUsdX18.intoSD59x18().add(totalDebtUsdX18);
198: }
In getCreditCapacityUsd(), it adds total debt to delegated credit but it's incorrect because a negative total debt means that the market has more credit.
We can confirm that from getTotalDebt() and getRealizedDebtUsd(). When depositCreditForMarket() is called netUsdTokenIssuance is decreased which means that negative netUsdTokenIssuance and also debt mean that the market has more credit.
File: Market.sol
264: function getTotalDebt(Data storage self) internal view returns (SD59x18 totalDebtUsdX18) {
265: totalDebtUsdX18 = getUnrealizedDebtUsd(self).add(getRealizedDebtUsd(self));
266: }
File: Market.sol
234: function getRealizedDebtUsd(Data storage self) internal view returns (SD59x18 realizedDebtUsdX18) {
235:
236: UD60x18 creditDepositsValueUsdX18;
237:
238:
239: if (block.timestamp <= self.lastCreditDepositsValueRehydration) {
240: creditDepositsValueUsdX18 = ud60x18(self.creditDepositsValueCacheUsd);
241: } else {
242:
243: creditDepositsValueUsdX18 = getCreditDepositsValueUsd(self);
244: }
245:
246:
247:
248: realizedDebtUsdX18 = creditDepositsValueUsdX18.intoSD59x18().add(sd59x18(self.netUsdTokenIssuance));
249: }
File: CreditDelegationBranch.sol
212:
213: if (collateralAddr == usdToken) {
214:
215: market.updateNetUsdTokenIssuance(unary(amountX18.intoSD59x18()));
Impact
The system calculates the credit capacity incorrectly that will affect many operations.
Recommendations
Modify the credit capacity calculation to subtract total debt from delegated credit instead of adding it.