Core Contracts

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

Incorrect amount transferred from user during debt repayment

Summary

The _repay and finalizeLiquidation functions in the LendingPool smart contract incorrectly transfer scaled amount of tokens, amountScaled, instead of the amount of underlying, amountBurned, returned from the DebtToken::burn, which is meant to be the amount of DebtTokens burned in units of the underlying asset. This results in a mismatch between the debt reduction and the actual amount repaid, leading to financial inconsistencies in the protocol.

Vulnerability Details

In the _repay and finalizeLiquidation function, the following line executes the transfer of reserve assets:

// Transfer reserve assets from the caller (msg.sender) to the reserve
IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountScaled);

Issue:

  • The function transfers amountScaled, which is derived from the internal debt token calculations.

  • The expected behavior is to transfer the actual repayment amount, amountBurned, returned from the DebtToken::burn, which is meant to be the reserveAsstet worth of the debtTokens burned, taking account of the accrued interest

  • amountScaled does not match the expected underlying token amount due to scaling differences, the repayment would be inaccurate, leading to inconsistencies between debt accounting and actual asset movements.

Impact

  • Accounting Inconsistencies: The protocol's debt and collateral accounting may become unreliable, affecting liquidation calculations and reserve balances.

  • Potential Exploitation: If the issue allows users to manipulate repayment calculations, it could be used for unintended financial gains.

Tools Used

Manual Review

Recommendations

Ensure that the amount transferred matches the repayment amount with the interest accrued accounted for in units of the underlying assets. Consider the following changes:

// Transfer reserve assets from the caller (msg.sender) to the reserve
- IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountScaled);
+ IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountBurned);
Updates

Lead Judging Commences

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

DebtToken::burn incorrectly burns amount (asset units) instead of amountScaled (token units), breaking token economics and interest-accrual mechanism

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

DebtToken::burn incorrectly burns amount (asset units) instead of amountScaled (token units), breaking token economics and interest-accrual mechanism

Support

FAQs

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