Core Contracts

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

Inconsistent benchmark rate logic in emission rate calculation

Summary

The calculateNewEmissionRate() function implements contradictory logic for the benchmarkRate, using it as both a floor and a ceiling in different scenarios. This creates a mechanism that works against its intended purpose of maintaining effective emission rate adjustments.

Vulnerability Details

// When utilization is high (lines 225-227):
uint256 increasedRate = emissionRate + adjustment;
uint256 maxRate = increasedRate > benchmarkRate ? increasedRate : benchmarkRate;
return maxRate < maxEmissionRate ? maxRate : maxEmissionRate;
// When utilization is low (lines 229-231):
uint256 decreasedRate = emissionRate > adjustment ? emissionRate - adjustment : 0;
uint256 minRate = decreasedRate < benchmarkRate ? decreasedRate : benchmarkRate;
return minRate > minEmissionRate ? minRate : minEmissionRate;

The function uses benchmarkRate in two contradictory ways:

  1. As a floor when utilization is high, taking the higher value between increasedRate and benchmarkRate

  2. As a ceiling when utilization is low, taking the lower value between decreasedRate and benchmarkRate

Intent: Benchmark as the target emission rate: If the goal is for the emission rate to tend towards benchmarkRate based on utilization, this logic isn’t achieving that. When over-utilized, you only increase up to maxEmissionRate, but benchmarkRate is a floor. When under-utilized, you only decrease down to minEmissionRate, but benchmarkRate is a ceiling. It creates a sticky effect.
Potential Stalling: If the utilization rate fluctuates around the target, but stays just on one side for a prolonged period, the emission rate might get stuck at either the minEmissionRate or the maxEmissionRate, even if the utilization would ideally want it closer to the benchmarkRate.
Unintended Minimum/Maximum Values: If the utilization rate continues to drop dramatically, you might want the emission rate to eventually fall below benchmarkRate so that you can lower the token emissions as far as possible. However, this logic prevents that.

Impact

  1. The emission rate becomes stuck at the benchmark rate when crossing the utilization target threshold

  2. The adjustment mechanism fails to respond to utilization changes as designed

  3. The system's ability to incentivize desired utilization levels through emission rate adjustments breaks down

Tools Used

Manual code review

Recommendations

Implement consistent benchmark rate logic by using it as a floor only:

function calculateNewEmissionRate() internal view returns (uint256) {
uint256 utilizationRate = getUtilizationRate();
uint256 adjustment = (emissionRate * adjustmentFactor) / 100;
if (utilizationRate > utilizationTarget) {
uint256 increasedRate = emissionRate + adjustment;
uint256 adjustedRate = increasedRate > benchmarkRate ? increasedRate : benchmarkRate;
return adjustedRate < maxEmissionRate ? adjustedRate : maxEmissionRate;
} else if (utilizationRate < utilizationTarget) {
uint256 decreasedRate = emissionRate > adjustment ? emissionRate - adjustment : 0;
return decreasedRate > minEmissionRate ? decreasedRate : minEmissionRate;
}
return emissionRate;
}

This change ensures:

  1. The benchmark rate serves as a consistent floor

  2. The emission rate adjusts smoothly based on utilization

  3. The system maintains proper bounds with minEmissionRate and maxEmissionRate

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!