Core Contracts

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

potential reentrancy vulnerability

Summary

GaugeController.sol::_distributeToGauges
A potential reentrancy vulnerability exists in the GaugeController._distributeToGauges function due to an external call to IGauge(gauge).notifyRewardAmount(gaugeShare) without proper reentrancy protection. This could allow a malicious gauge contract to re-enter the GaugeController contract and manipulate its state.

Vulnerability Details

The _distributeToGauges function distributes rewards to gauges based on their weights. It calculates the share of rewards for each gauge and then makes an external call to the gauge contract using IGauge(gauge).notifyRewardAmount(gaugeShare). This external call is made without any reentrancy protection, which could allow a malicious gauge contract to re-enter the GaugeController contract before the state updates are finalized.

POC (Proof of Concept)
A malicious gauge contract is added to the system.

The distributeRevenue function is called, which internally calls _distributeToGauges.

When _distributeToGauges makes the external call to notifyRewardAmount, the malicious gauge contract re-enters the GaugeController contract.

During reentrancy, the malicious contract could:

Manipulate gauge weights.

Re-enter the reward distribution process to claim more rewards than intended.

Exploit other functions in the GaugeController contract.

Impact

Funds Loss: Incorrect reward distributions could lead to loss of funds.

State Manipulation: A malicious gauge contract could manipulate the state of the GaugeController contract, such as changing gauge weights or re-entering the distribution process.

System Instability: Reentrancy attacks could destabilize the protocol and undermine user trust.

Tools Used

Manual Review

Recommendations

1- Apply the nonReentrant Modifier:

Add the nonReentrant modifier to the distributeRevenue function to prevent reentrancy.

function distributeRevenue(
GaugeType gaugeType,
uint256 amount
) external onlyRole(EMERGENCY_ADMIN) whenNotPaused nonReentrant {
// Function logic
}

2- Follow Checks-Effects-Interactions Pattern:

Ensure that all state changes are completed before making external calls. Track the total distributed amount and update the state after external calls.

function _distributeToGauges(
GaugeType gaugeType,
uint256 amount
) internal {
uint256 totalDistributed = 0;
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) {
totalDistributed += gaugeShare;
IGauge(gauge).notifyRewardAmount(gaugeShare); // External call
}
}
}
// Update state after external calls
revenueShares[gaugeType] -= totalDistributed;
}
Updates

Lead Judging Commences

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

Support

FAQs

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