Core Contracts

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

The emergency shutdown mechanism in `RAACMinter` sets emission rate to 0 without a way to restore it, permanently disabling token minting even after unpausing.

Summary

The RAACMinter::emergencyShutdown() function sets emission rate to 0 without a way to restore it, making it impossible to resume normal protocol operations after an emergency shutdown.

Vulnerability Details

In RAACMinter::emergencyShutdown(), the emission rate is set to 0:

function emergencyShutdown(bool updateLastBlock, uint256 newLastUpdateBlock) external onlyRole(DEFAULT_ADMIN_ROLE) {
emissionRate = 0; // @audit-issue: No way to restore this
_pause();
if (updateLastBlock) {
_setLastUpdateBlock(newLastUpdateBlock);
}
emit EmergencyShutdown(msg.sender, lastUpdateBlock);
}

The issue is that once set to 0, there is no direct way to restore the emission rate. The only function that can modify emission rate is updateEmissionRate(), but this function calculates adjustments based on the current rate:

function calculateNewEmissionRate() internal view returns (uint256) {
uint256 utilizationRate = getUtilizationRate();
uint256 adjustment = (emissionRate * adjustmentFactor) / 100;
// Any adjustment to 0 will remain 0
...
}

Since adjustments are calculated as percentages of the current rate, when the rate is 0, all adjustments will also be 0.

Impact

  • Protocol cannot resume normal operations after emergency shutdown

  • Permanent loss of emission functionality unless contract is redeployed

Proof of Concept

  1. Admin calls emergencyShutdown() setting emission rate to 0

  2. Later tries to resume operations by calling unpause()

  3. updateEmissionRate() is called but cannot increase rate from 0

  4. tick() function mints 0 tokens (emissionRate * blocksSinceLastUpdate = 0)

Recommendations

1) Add a recovery function to restore emission rate:

+ function restoreEmissionRate(uint256 _newRate) external onlyRole(DEFAULT_ADMIN_ROLE) {
+ require(paused(), "Must be paused");
+ require(_newRate <= maxEmissionRate, "Rate too high");
+ require(_newRate >= minEmissionRate, "Rate too low");
+ emissionRate = _newRate;
+ emit EmissionRateRestored(_newRate);
+ }

2) Store the pre-shutdown emission rate:

+ uint256 public lastEmissionRate;
function emergencyShutdown(...) {
+ lastEmissionRate = emissionRate;
emissionRate = 0;
_pause();
}
function unpause(...) {
_unpause();
+ emissionRate = lastEmissionRate;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!