Core Contracts

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

Interest Continues to Accrue During Protocol Pause While Preventing Liquidation Close

Summary

When the protocol is paused, users cannot close liquidations through closeLiquidation(), but interest continues to accrue through the usageIndex. This means users in liquidation state can't exit their position while their debt keeps growing, potentially making their position irreparable when the protocol unpauses.

Vulnerability Details

In LendingPool.sol:

function closeLiquidation() external nonReentrant whenNotPaused {
address userAddress = msg.sender;
if (!isUnderLiquidation[userAddress]) revert NotUnderLiquidation();
// ... rest of code
}

Meanwhile, interest continues to accrue through the usageIndex update in ReserveLibrary:

function updateReserveState(ReserveData storage reserve, ReserveRateData storage rateData) {
uint256 timeDelta = block.timestamp - uint256(reserve.lastUpdateTimestamp);
// Interest keeps compounding even during pause
reserve.usageIndex = calculateUsageIndex(
rateData.currentUsageRate,
timeDelta,
reserve.usageIndex
);
}

The issue sequence:

  1. User's position becomes liquidatable

  2. Protocol gets paused for any reason

  3. User cannot close their liquidation due to whenNotPaused modifier

  4. Interest continues accruing during the pause

  5. When protocol unpauses, the user's debt has grown substantially

  6. Position might become impossible to save due to accumulated interest

Impact

High severity because:

  • Users lose control over their positions during pause

  • Debt grows without possibility of repayment

  • Could lead to forced liquidations after unpause, because the grace time may expired due to the pause

  • Disproportionately affects users already in distress

Recommendations

Allow closeLiquidation() to work during pause:

- function closeLiquidation() external nonReentrant whenNotPaused {
+ function closeLiquidation() external nonReentrant {

Add pause time tracking:

contract LendingPool {
uint256 public pauseStartTime;
uint256 public totalPausedTime;
function _pause() internal override {
super._pause();
pauseStartTime = block.timestamp;
}
function _unpause() internal override {
totalPausedTime += block.timestamp - pauseStartTime;
super._unpause();
}
}

Modify interest calculation to exclude paused time:

function updateReserveState(ReserveData storage reserve, ReserveRateData storage rateData) {
uint256 timeDelta = block.timestamp - uint256(reserve.lastUpdateTimestamp);
// Subtract paused time from interest calculation
timeDelta = timeDelta - totalPausedTime;
// ... rest of function
}

This ensures users aren't unfairly penalized during protocol pauses and maintains their ability to close liquidations during emergencies.

Would you like me to elaborate on any part of this analysis?

Updates

Lead Judging Commences

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

Unfair Liquidation As Borrow Interest Accumulates While Paused

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

Unfair Liquidation As Borrow Interest Accumulates While Paused

Support

FAQs

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