Core Contracts

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

Wrong representation of `totalDebt` will lead to wrong variable state updates in `ReserveLibrary`

Summary

This is due to the fact that reserve.totalUsage is denominated in double scaled crvUSD tokens

Vulnerability Details

The ReserveLibrary::calculateUtilizationRate function aims to represent the total borrowed amount as a percent from the total assets ever deposited in the LendingPool (totalLiquidity + totalDebt = all of the crvUSD ever deposited in the pool). This is impossible due to the way that reserve.totalUsage is denominated. Lets track it:

  1. reserve.totalUsage means to represent the total supply of DebtTokens

  2. When someone borrows funds he is minted DebtToken corresponding to his borrow. The amount is firstly scaled in the DebtToken::_update function, and then, when the totalSupply function is returned from the DebtToken::mint function it is scaled again, as can be seen here:

function _update(
address from,
address to,
uint256 amount
) internal virtual override {
if (from != address(0) && to != address(0)) {
revert TransfersNotAllowed(); // Only allow minting and burning
}
@> uint256 scaledAmount = amount.rayDiv(
ILendingPool(_reservePool).getNormalizedDebt()
);
super._update(from, to, scaledAmount);
emit Transfer(from, to, amount);
}

And here:

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

The problem here comes when we realise that the totalLiquidity amount in the function is denominate in crvUSD and the total borrowed amount is denominated in double scaled crvUSD. It will not represent the percentage correctly, which may lead to some unexpected and inaccurate updates during the updateInterestRatesAndLiquidity function (the calculateUtilizationRate function calculates the rate which is then used for other state updates)

Root Cause

I want to emphasized the fact that the root cause of this issue is not the double scaling. Even thought the double scaling in the totalSupply function may be unintended and it's not right, if it is not there and the DebtToken::totalSupply function just returns from super.totalSupply the issue remains because the reserve.totalUsage still won't be denominated in crvUSD as it is required to be for the calculateUtilizationRate function.

Impact

Leads to wrong variable state updates, which will mess up the minting and burning of rToken and DebtToken

Tools Used

Manual Review

Recommendations

Unscale the amount to the state that it represents crvUSD

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!