Core Contracts

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

Overpayment Without Refund in Debt Repayment Function

Summary

The LendingPool::_repay function in the protocol allows users to repay their outstanding debt. However, due to the way repayment amounts are handled, users may overpay without receiving a refund, leading to fund loss and misaccounting in the protocol. The issue arises because the function transfers amountScaled, which may be greater than the actual debt burned (amountBurned). Over time, this can result in significant user losses and inaccurate reserve balances. A proper fix involves ensuring that only the exact `amountBurned` is transferred and refunding any excess repayment to the user.

Vulnerability Details

🔍 Issue: Overpayment Without Refund in _repay Function

📌 Affected Code:

// Transfer reserve assets from the caller (msg.sender) to the reserve
IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountScaled); // @audit-issue overpayment without refund

CopyEdit

// Transfer reserve assets from the caller (msg.sender) to the reserve IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountScaled); // @audit-issue overpayment without refund

  • The function burns the user's debt tokens based on amountBurned, but transfers amountScaled, which may be greater than the actual required repayment.

  • There is no refund mechanism, meaning any excess payment is permanently lost.

🛑 How the Vulnerability Manifests:

  1. User intends to repay their full debt.

  2. The function calculates the amount to burn (amountBurned), which may be slightly less than the scaled debt (amountScaled).

  3. More tokens are transferred (amountScaled), but the extra amount is not burned or refunded.

  4. The user overpays, losing excess funds permanently.

Impact

📉 Real-World Example: Impact on Users

Let’s assume the following:

  • userDebt = 1,000 tokens

  • usageIndex = 1.25

  • amount = 1,000 tokens (User intends to repay the full debt)

Expected Debt Repayment Calculation:

userScaledDebt=10001.25=800 tokens\text{userScaledDebt} = \frac{1000}{1.25} = 800 \text{ tokens}userScaledDebt=1.251000​=800 tokensactualRepayAmount=min⁡(1000,800)=800 tokens\text{actualRepayAmount} = \min(1000, 800) = 800 \text{ tokens}actualRepayAmount=min(1000,800)=800 tokensscaledAmount=8001.25=640 tokens\text{scaledAmount} = \frac{800}{1.25} = 640 \text{ tokens}scaledAmount=1.25800​=640 tokens

🔹 Potential Overpayment:

  • If amountBurned = 800 tokens, but amountScaled = 640 tokens, then the function might transfer 640 tokens instead of burning 800, leading to inconsistencies.

  • If instead amountScaled is higher than amountBurned, then the user loses the difference, permanently overpaying without a refund.


📊 Long-Term Effects on the Protocol

  1. User Overpayment:

    • If thousands of users repay their loans, small rounding errors accumulate, leading to massive fund losses over time.

  2. Liquidity Distortion:

    • The reserve may hold excess funds due to overpayments, creating inconsistencies in available liquidity versus reported debt.

  3. Protocol Accounting Errors:

    • Since overpaid amounts are not burned, the debt-to-reserve ratio becomes inaccurate, leading to unexpected liquidity constraints or incorrect interest rate calculations.

Tools Used

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/LendingPool/LendingPool.sol#L423

Recommendations

implement overpayment refunds

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!