Core Contracts

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

[H] Incorrect Scaling in `totalSupply` Function in `DebtToken`

Summary

The totalSupply function in the DebtToken contract incorrectly divides the total supply by the normalized debt instead of multiplying it. And, in the LendingPool contract, the borrow and repay functions equate totalSupply to totalUsage, which affects the utilization rate and the accounting of the protocol.

Vulnerability Details

The current totalSupply function in the DebtToken contract is:

function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledSupply = super.totalSupply();
return scaledSupply.rayDiv(ILendingPool(_reservePool).getNormalizedDebt());
}

The totalSupply function incorrectly divides the total supply by the normalized debt. It should multiply the total supply by the normalized debt.

In the LendingPool contract, the borrow and repay functions equate totalSupply to totalUsage:

// In the borrow function
reserve.totalUsage = newTotalSupply;
// In the repay function
reserve.totalUsage = newTotalSupply;

This affects the utilization rate and the accounting of the protocol.

Links to the issues:

  1. https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/DebtToken.sol#L233

  2. https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/LendingPool/LendingPool.sol#L360

  3. https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/LendingPool/LendingPool.sol#L424

POC

copy paste this below test in LendingPooin Borrow and Repayblock

it.only("Incorrect TotalSupply calculation", async function () {
const borrowAmount = ethers.parseEther("50");
console.log("total supply of Debt Token before borrow", formatEther(await debtToken.totalSupply()));
console.log("user 1 debt balance before borrow", formatEther(await debtToken.balanceOf(user1.address)));
await lendingPool.connect(user1).borrow(borrowAmount);
console.log("total supply of Debt Token after borrow", formatEther(await debtToken.totalSupply()));
console.log("user 1 debt balance after borrow", formatEther(await debtToken.balanceOf(user1.address)));
const crvUSDBalance = await crvusd.balanceOf(user1.address);
expect(crvUSDBalance).to.equal(ethers.parseEther("1050"));
const debtBalance = await debtToken.balanceOf(user1.address);
const totalSupply = await debtToken.totalSupply();
expect(debtBalance).to.gt(totalSupply);
});

The Output should be

total supply of Debt Token before borrow 0.0
user 1 debt balance before borrow 0.0
total supply of Debt Token after borrow 49.999999524353122506
user 1 debt balance after borrow 50.0

Impact

This issue can lead to incorrect calculations of the total supply and utilization rate, potentially causing issues with token accounting and the overall protocol's functionality.

Tools Used

Manual code review.

Recommendations

Update the totalSupply function to correctly multiply the total supply by the normalized debt. Additionally, update the borrow and repay functions in the LendingPool contract to correctly handle the totalUsage.

Corrected totalSupply Function in DebtToken

function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledSupply = super.totalSupply();
return scaledSupply.rayMul(ILendingPool(_reservePool).getNormalizedDebt());
}

This ensures that the correct calculations are made for the total supply and utilization rate, leading to accurate token accounting and protocol functionality.


Updates

Lead Judging Commences

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

DebtToken::totalSupply incorrectly uses rayDiv instead of rayMul, severely under-reporting total debt and causing lending protocol accounting errors

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

DebtToken::totalSupply incorrectly uses rayDiv instead of rayMul, severely under-reporting total debt and causing lending protocol accounting errors

Support

FAQs

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

Give us feedback!