Core Contracts

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

Incorrect Debt Amount Transfer During finalize Liquidation through stability pool.

## Summary

In the finalizeLiquidation function, when liquidating a user's position, the debt is calculated as user.scaledDebtBalance.rayMul(reserve.usageIndex). This debt amount is passed to the burn function, but there is an issue: the burn function scales the debt to the user's balance, which is smaller than the actual debt. This leads to the wrong amount of debt being transferred, causing an incomplete liquidation. Instead of transferring the full user debt amount, only a user balance value is transferred, leaving their position under-closed.


## Vulnerability Details

  • Issue:

    • In the finalizeLiquidation function, the debt is calculated using rayMul on the user's scaledDebtBalance with the usageIndex, which increases the debt value.

    • However, in the burn function, the amount is greater than user balance it will set it max user balance and return that revised amount from burn function as AmountScaled.(which is wrong)

      uint256 userDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex); // User debt after scaling
      (uint256 amountScaled, uint256 newTotalSupply, uint256 amountBurned, uint256 balanceIncrease) = IDebtToken(reserve.reserveDebtTokenAddress).burn(userAddress, userDebt, reserve.usageIndex);

      back in lending pool, they will amontScaled value retunr from burn function, which is user DEBT token value not actual amount they borrwed

      IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountScaled);
  • Root Cause:

    • The **finialize **function pass the wrong amount parameter while Transferringf asset from stablity pool contract

  • Example > user borrowd 1000 Tokens and, have Debt balance as 500 tokens

    , contract pass 1000 amt to burn function which revise it to 500 and return same value as first paramter,

  • then finialize transfer assuen user total debt is 500 tokens and Transfer Frm stablity pool

  • But user total debt was 1000 tokens, so liquidation is incomplete.


## Impact

  • Incomplete Liquidation:

    • The user’s position is not fully closed because the wrong amount of debt is transferred and burned. The user might still owe a portion of the debt after liquidation, leading to an incorrect state in the contract.


## Tools Used

  • Code review and manual inspection of the contract's debt handling functions.


## Recommendations

In the finalizeLiquidation function, while Transferring the user total debt, use userDebt which represent there totalDebt value because this function completely close user position so it need to pay pay complete borrowed amt, so don't use amountScaled for Transferring asset instead user Debt vraible

@> change to userDebt IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, userDebt);
Updates

Lead Judging Commences

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

LendingPool::finalizeLiquidation passes normalized userDebt to DebtToken::burn which compares against scaled balance, causing incomplete debt clearance while taking all collateral

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

LendingPool::finalizeLiquidation passes normalized userDebt to DebtToken::burn which compares against scaled balance, causing incomplete debt clearance while taking all collateral

Support

FAQs

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