Core Contracts

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

Unnecessary External Contract Call for veRAACToken Retrieval Leading to Increased Gas Costs in BaseGauge.sol

Summary

The _applyBoost function retrieves the veRAACToken contract address from the IGaugeController(controller) on every function call, which introduces unnecessary gas costs due to repeated external contract calls. This could be optimized by storing the token address in the contract's constructor instead of fetching it dynamically.

Vulnerability Details

External contract calls (like controller.veRAACToken()) are expensive, as they require reading storage from another contract.

Since the veRAACToken address is unlikely to change, storing it once in the constructor would save gas on every function execution.

function _applyBoost(address account, uint256 baseWeight) internal view virtual returns (uint256) {
if (baseWeight == 0) return 0;
>> IERC20 veToken = IERC20(IGaugeController(controller).veRAACToken()); // could be stored in the constructor instead of calling it everytime
uint256 veBalance = veToken.balanceOf(account);
uint256 totalVeSupply = veToken.totalSupply();
// Create BoostParameters struct from boostState
BoostCalculator.BoostParameters memory params = BoostCalculator.BoostParameters({
maxBoost: boostState.maxBoost,
minBoost: boostState.minBoost,
boostWindow: boostState.boostWindow,
totalWeight: boostState.totalWeight,
totalVotingPower: boostState.totalVotingPower,
votingPower: boostState.votingPower
});
uint256 boost = BoostCalculator.calculateBoost(
veBalance,
totalVeSupply,
params
);
return (baseWeight * boost) / 1e18;
}

Impact

Higher Gas Costs per Call

  • Every function execution requires an extra external call to fetch veRAACToken, increasing transaction costs.

  • This issue is amplified in high-frequency function calls, such as within staking, voting, or reward distribution mechanisms.

Unnecessary External Dependency

  • If the external call fails due to unforeseen reasons (e.g., controller malfunction), _applyBoost will fail even though the token address is known.

  • This adds unnecessary complexity and potential failure points.

Reduced Efficiency & Scalability

  • Fetching the token dynamically does not provide additional benefits, and storing it once would improve contract efficiency.

  • Gas costs can accumulate, making the contract less competitive compared to optimized alternatives.

Tools Used

Manual Review

Recommendations

Add this to constructor :

constructor(address _controller) {

controller = _controller;

veToken = IERC20(IGaugeController(controller).veRAACToken()); // Store once

}

function _applyBoost(address account, uint256 baseWeight) internal view virtual returns (uint256) {
if (baseWeight == 0) return 0;
>> uint256 veBalance = veToken.balanceOf(account); // Uses stored token address
uint256 totalVeSupply = veToken.totalSupply();
BoostCalculator.BoostParameters memory params = BoostCalculator.BoostParameters({
maxBoost: boostState.maxBoost,
minBoost: boostState.minBoost,
boostWindow: boostState.boostWindow,
totalWeight: boostState.totalWeight,
totalVotingPower: boostState.totalVotingPower,
votingPower: boostState.votingPower
});
uint256 boost = BoostCalculator.calculateBoost(
veBalance,
totalVeSupply,
params
);
return (baseWeight * boost) / 1e18;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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