Core Contracts

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

Lack of Comprehensive Pausability for Critical Functions.

Summary

The BaseGauge contract features a whenNotPaused modifier that is currently only applied to the BaseGauge::getReward() and BaseGauge::voteDirection() function. This limited application of the pausing functionality could leave critical operations exposed during emergencies, potentially jeopardizing the safety of staked assets and reward distributions.

Vulnerability Details

The whenNotPaused modifier is used only in 2 functions first is getReward() function SLOC#327-347, which allows users Claims accumulated rewards:

// File: contracts/core/governance/gauges/BaseGauge.sol
function getReward() external virtual nonReentrant whenNotPaused updateReward(msg.sender) {
if (block.timestamp - lastClaimTime[msg.sender] < MIN_CLAIM_INTERVAL) {
revert ClaimTooFrequent();
}
lastClaimTime[msg.sender] = block.timestamp;
UserState storage state = userStates[msg.sender];
uint256 reward = state.rewards;
if (reward > 0) {
state.rewards = 0;
uint256 balance = rewardToken.balanceOf(address(this));
if (reward > balance) {
revert InsufficientBalance();
}
rewardToken.safeTransfer(msg.sender, reward);
emit RewardPaid(msg.sender, reward);
}
}

and second is voteDirection() function SLOC#407-420, which allows users to vote on direction:

// File: contracts/core/governance/gauges/BaseGauge.sol
function voteDirection(uint256 direction) public whenNotPaused updateReward(msg.sender) {
if (direction > 10000) revert InvalidWeight();
uint256 votingPower = IERC20(IGaugeController(controller).veRAACToken()).balanceOf(msg.sender);
if (votingPower == 0) revert NoVotingPower();
totalVotes = processVote(
userVotes[msg.sender],
direction,
votingPower,
totalVotes
);
emit DirectionVoted(msg.sender, direction, votingPower);
}

stake() and withdraw() functions that allow users to Stakes tokens in the gauge, and withdraw staked tokens are not protected by the pausing mechanism.

notifyRewardAmount()function facilitates the Notifies about new reward amount and is not covered by the pausing control.

// File: contracts/core/governance/gauges/BaseGauge.sol
function stake(uint256 amount) external nonReentrant updateReward(msg.sender) { // <@ POC
// File: contracts/core/governance/gauges/BaseGauge.sol
function withdraw(uint256 amount) external nonReentrant updateReward(msg.sender) { // <@ POC
// File: contracts/core/governance/gauges/BaseGauge.sol
function notifyRewardAmount(uint256 amount) external override onlyController updateReward(address(0)) { // <@ POC

Impact

The lack of comprehensive pause functionality exposes the contract to potential issues if the contract needs to be paused for maintenance or in response to an attack. By not restricting all non-migration functions during a pause, users can still interact with the contract in ways that may not be intended during a paused state, i.e. if an emergency occurs (e.g., a security vulnerability is discovered), the contract cannot be fully paused to protect funds and prevent unauthorized transactions. This could lead to:

  1. Unauthorized withdrawals and claims of rewards during a security breach.

  2. Potential loss of staked tokens and rewards if a vulnerability is exploited before a fix can be applied.

  3. Increased risk to user assets, as pausing is a common safeguard to mitigate damage during incidents.

Tools Used

  • Manual Review

Recommended Mitigation

Apply whenNotPaused modifier to mentioned critical functions.

Updates

Lead Judging Commences

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

BaseGauge::withdraw, stake, and checkpoint functions lack whenNotPaused modifier, allowing critical state changes even during emergency pause

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

BaseGauge::withdraw, stake, and checkpoint functions lack whenNotPaused modifier, allowing critical state changes even during emergency pause

Support

FAQs

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

Give us feedback!