Core Contracts

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

Unsafe Interest Rates

Summary

The ReserveLibrary contract calculates borrowing and liquidity rates using parameters (optimalUtilizationRate, baseRate, primeRate, etc.) that lack validation, allowing them to be set to mathematically invalid or dangerous values. This can result in negative interest rates, arithmetic overflows, or unsustainable rate spikes, destabilizing the protocol’s lending/borrowing equilibrium.

Code Snippet

Vulnerability Details

Exploit Scenerio

Set Invalid Parameters: Admin configures optimalUtilizationRate to 150% (exceeding 100%).

Trigger Rate Calculation: When utilization exceeds 100%, the interest rate formula breaks.

Protocol Malfunction: Borrowing/lending functions fail due to invalid rates.

Code Proof:

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/libraries/pools/ReserveLibrary.sol#L270

In ReserveLibrary.sol, the calculateBorrowRate function lacks bounds checks:

function calculateBorrowRate(
uint256 primeRate,
uint256 baseRate,
uint256 optimalRate,
uint256 maxRate,
uint256 optimalUtilizationRate,
uint256 utilizationRate
) internal pure returns (uint256) {
// No validation for optimalUtilizationRate <= 100%
if (utilizationRate <= optimalUtilizationRate) {
// If optimalUtilizationRate > 100%, this branch is unreachable
uint256 rateSlope = primeRate - baseRate;
uint256 rateIncrease = utilizationRate.rayMul(rateSlope).rayDiv(optimalUtilizationRate);
rate = baseRate + rateIncrease;
} else {
// Incorrect calculations if optimalUtilizationRate >= 100%
uint256 excessUtilization = utilizationRate - optimalUtilizationRate;
uint256 rateSlope = maxRate - primeRate;
uint256 rateIncrease = excessUtilization.rayMul(rateSlope).rayDiv(WadRayMath.RAY - optimalUtilizationRate);
rate = primeRate + rateIncrease;
}
return rate;
}

Attack Simulation:

  • Parameters:

optimalUtilizationRate = 150% (1.5e27 in Ray)

utilizationRate = 100% (1e27)

  • Calculation:
    Since utilizationRate (1e27) ≤ optimalUtilizationRate (1.5e27), the formula attempts:

rateSlope = primeRate - baseRate;
rateIncrease = (1e27 * rateSlope) / 1.5e27;
rate = baseRate + rateIncrease;

Since the primeRate < baseRate, this produces a negative rate, crashing the protocol.

Impact

Rates can become invalid (e.g., >100%), crashing the protocol.

Tools Used

Manual review

Recommendations

Enforce strict bounds on interest rate parameters

// In ReserveLibrary.sol
function calculateBorrowRate(...) internal pure {
require(optimalUtilizationRate <= 100, "Invalid optimal rate");
...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 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.