Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Valid

Double Scaling of User Debt in `liquidateBorrower` Function in stability pool contract

## Summary

The liquidateBorrower function in the StabilityPool contract contains an issue where the user's debt is incorrectly scaled twice. When retrieving the user's debt from the LendingPool with the getUserDebt function, the debt value is already scaled using the usageIndex. However, the function liquidateBorrower applies the scaling again by calling rayMul on the returned debt, effectively doubling the scaling factor. This leads to an overestimation of the debt amount, which could result in incorrect approval amounts being sent to the LendingPool and potentially incorrect liquidation.


## Vulnerability Details

  • Issue:

    • In the liquidateBorrower function, the code calls the getUserDebt function to retrieve the user's debt. The getUserDebt function already applies a scaling factor (rayMul) to the debt using the usageIndex in the LendingPool.

    • However, the liquidateBorrower function again applies another rayMul on the debt value to calculate scaledUserDebt, leading to a double scaling of the debt amount.

      uint256 userDebt = lendingPool.getUserDebt(userAddress); // already scaled
      uint256 scaledUserDebt = WadRayMath.rayMul(userDebt, lendingPool.getNormalizedDebt()); // scales again, incorrect
  • Root Cause:
    The getUserDebt function already applies scaling on the debt, so applying rayMul a second time is incorrect. This causes the debt value to be inflated by an additional factor, leading to an overestimation of the debt.

  • Expected Behavior:

    • The correct approach would be to reverse the scaling on the debt using rayDiv before performing any approval or transfer, as this would give the actual debt value the borrower owes to the LendingPool.

    • The debt should not be scaled again after it has already been scaled once.


## Impact

  • Overestimation of Debt:
    By applying scaling twice, the amount of debt approved for liquidation is inflated. This means the StabilityPool would approve and transfer more funds than necessary to the LendingPool, which could result in unintended financial discrepancies, such as excess tokens being transferred or incorrect liquidation.

  • Incorrect Liquidation:
    Liquidation may not happen correctly due to the overestimation of the debt amount, potentially leading to the borrower’s debt being overpaid or underpaid depending on the liquidation outcome.

  • Token Wastage:
    The overestimation of the debt may cause the StabilityPool to approve more tokens than necessary, eading to a loss of funds for the pool due to approval more than required.


## Tools Used

  • Manual code review


## Recommendations

  1. Fix the Double Scaling Issue:
    Instead of scaling the user’s debt again after retrieving it with getUserDebt, reverse the scaling to get the actual debt amount by using rayDiv with the usageIndex.

    Example of corrected code:

    uint256 userDebt = lendingPool.getUserDebt(userAddress); // Debt already scaled
    uint256 scaledUserDebt = userDebt.rayDiv(lendingPool.getNormalizedDebt()); // Reverse the scaling with rayDiv
  2. Ensure Correct Approval:
    After fixing the double scaling issue, ensure that the correct amount is approved for the liquidation. The approval should match the actual debt, not an inflated value.

Updates

Lead Judging Commences

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

StabilityPool::liquidateBorrower double-scales debt by multiplying already-scaled userDebt with usage index again, causing liquidations to fail

Support

FAQs

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