Core Contracts

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

Gas Limit Exhaustion and Denial of Service Due to Unchecked Array Length in _distributeToGauges

Summary:

GaugeController.sol

function _distributeToGauges(
GaugeType gaugeType,
uint256 amount
) internal {
uint256 totalTypeWeight = 0;
uint256[] memory gaugeWeights = new uint256[](_gaugeList.length);
uint256 activeGaugeCount = 0;
// First pass: calculate total weight and store gauge weights
for (uint256 i = 0; i < _gaugeList.length; i++) {
address gauge = _gaugeList[i];
if (gauges[gauge].isActive && gauges[gauge].gaugeType == gaugeType) {
gaugeWeights[i] = gauges[gauge].weight;
totalTypeWeight += gaugeWeights[i];
activeGaugeCount++;
}
}
if (totalTypeWeight == 0 || activeGaugeCount == 0) return;
// Second pass: distribute rewards
for (uint256 i = 0; i < _gaugeList.length; i++) {
address gauge = _gaugeList[i];
if (gauges[gauge].isActive && gauges[gauge].gaugeType == gaugeType) {
uint256 gaugeShare = (amount * gaugeWeights[i]) / totalTypeWeight;
if (gaugeShare > 0) {
IGauge(gauge).notifyRewardAmount(gaugeShare);
}
}
}
}

The function _distributeToGauges iterates over the entire _gaugeList twice, which can lead to high gas consumption if the list size becomes large. This is a risk if an external actor can influence the array length, as they can add many elements, causing the function to exceed the gas limit and fail. This could result in a Denial of Service (DoS) attack, where the distribution of rewards becomes impossible.

Vulnerability Details:

Gas Consumption Risk: The function performs two loops over _gaugeList, which can result in high gas costs if the list is large.

External Manipulation: An attacker can increase the list size by adding gauges, potentially leading to excessive gas usage and failed transactions.

Impact:

Denial of Service (DoS): Excessive gas usage can prevent reward distribution from being processed correctly.

Exploitable by Adversaries: An attacker can manipulate the array length to cause the transaction to exceed the block gas limit, disrupting contract operations.

Proof of Concept (PoC):

An attacker could add a large number of gauges to the list, increasing gas usage during the loop:

function attackAddGauges(uint256 numGauges) external {for (uint256 i = 0; i < numGauges; i++) {_gaugeList.push(address(new Gauge())); // Add a large number of gauges}}

Tools Used: none

Recommendations:

Maintain a running total of gauge weights and only iterate over the relevant gauges. You can store a totalTypeWeight and gaugeWeights separately for active gauges to avoid looping through the entire array.

uint256 public totalTypeWeight; // Store total weight of active gauges
function \_distributeToGauges(GaugeType gaugeType, uint256 amount) internal {
uint256 totalTypeWeight = 0;
uint256\[] memory gaugeWeights = new uint256;
uint256 activeGaugeCount = 0;
// Update logic to only loop through active gauges
for (uint256 i = 0; i < _gaugeList.length; i++) {
address gauge = _gaugeList[i];
if (gauges[gauge].isActive && gauges[gauge].gaugeType == gaugeType) {
gaugeWeights[i] = gauges[gauge].weight;
totalTypeWeight += gaugeWeights[i];
activeGaugeCount++;
}
}
// Further logic as before...
}

By ensuring the weight is tracked and updated more efficiently, you eliminate the risk of excessive gas usage.

Updates

Lead Judging Commences

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

GaugeController._distributeToGauges iterates twice over unbounded gauges list without error handling, causing DoS risk from out-of-gas or single gauge revert

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

GaugeController._distributeToGauges iterates twice over unbounded gauges list without error handling, causing DoS risk from out-of-gas or single gauge revert

Support

FAQs

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

Give us feedback!