Summary
When calculating the RealizedDebtUsd
, there is an adding netUsdTokenIssuance
and creditDepositsValueUsd
instead of subtracting
them.
Vulnerability Details
234:function getRealizedDebtUsd(Data storage self) internal view returns (SD59x18 realizedDebtUsdX18) {
UD60x18 creditDepositsValueUsdX18;
if (block.timestamp <= self.lastCreditDepositsValueRehydration) {
creditDepositsValueUsdX18 = ud60x18(self.creditDepositsValueCacheUsd);
} else {
creditDepositsValueUsdX18 = getCreditDepositsValueUsd(self);
}
realizedDebtUsdX18 = creditDepositsValueUsdX18.intoSD59x18().add(sd59x18(self.netUsdTokenIssuance));
}
The creditDepositsValue represents the amount of loss the trader has incurred in perpEngin, which is sent to this market. This value should be deducted from the debt or increased by credit, but the implemented code does not do so.
Impact
Markets don't work as intended.
Incorrect accounting results in losses for providers or traders.
Recommendations
234:function getRealizedDebtUsd(Data storage self) internal view returns (SD59x18 realizedDebtUsdX18) {
// prepare the credit deposits usd value variable;
UD60x18 creditDepositsValueUsdX18;
// if the credit deposits usd value cache is up to date, return the stored value
if (block.timestamp <= self.lastCreditDepositsValueRehydration) {
creditDepositsValueUsdX18 = ud60x18(self.creditDepositsValueCacheUsd);
} else {
// otherwise, we'll need to loop over credit deposits to calculate it
creditDepositsValueUsdX18 = getCreditDepositsValueUsd(self);
}
// finally after determining the market's latest credit deposits usd value, sum it with the stored net usd
// token issuance to return the net realized debt usd value
- realizedDebtUsdX18 = creditDepositsValueUsdX18.intoSD59x18().add(sd59x18(self.netUsdTokenIssuance));
+ realizedDebtUsdX18 = unary(creditDepositsValueUsdX18.intoSD59x18()).add(sd59x18(self.netUsdTokenIssuance));
}