Core Contracts

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

Missing pausability enforcement during withdrawal of staked tokens

Summary

The BaseGauge contract inherits the pause functionality from Openzeppelin's Pausable contract. However, the whenNotPaused modifier that comes with this is not applied to functions that critically require it therefore exposing the protocol to more to risk during emergencies.

Vulnerability Details

The whenNotPaused modifier is used only in the voteDirection() and getReward() functions:

function getReward() external virtual nonReentrant whenNotPaused updateReward(msg.sender) {
---SNIP---
function voteDirection(uint256 direction) public whenNotPaused updateReward(msg.sender) {

However, the withdraw() function that allow users to withdraw staked tokens is not protected by the pausing mechanism.

function withdraw(uint256 amount) external nonReentrant updateReward(msg.sender) {
// @audit-issue Missing pause check
if (amount == 0) revert InvalidAmount();
if (_balances[msg.sender] < amount) revert InsufficientBalance();
_totalSupply -= amount;
_balances[msg.sender] -= amount;
stakingToken.safeTransfer(msg.sender, amount);
emit Withdrawn(msg.sender, amount);
}

Impact

By not restricting withdrawals during a pause, users can still interact with the contract in ways that may not be intended during a paused state, i.e. During an emergency, the contract cannot be fully paused to protect funds and prevent unauthorized transactions.

Tools Used

Manual Review

Recommendations

Enforce pausability during withdrawals:

- function withdraw(uint256 amount) external nonReentrant updateReward(msg.sender) {
+ function withdraw(uint256 amount) external nonReentrant whenNotPaused updateReward(msg.sender) {
if (amount == 0) revert InvalidAmount();
if (_balances[msg.sender] < amount) revert InsufficientBalance();
_totalSupply -= amount;
_balances[msg.sender] -= amount;
stakingToken.safeTransfer(msg.sender, amount);
emit Withdrawn(msg.sender, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 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 3 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.