Core Contracts

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

Emergency withdrawal breaks protocol accounting by not updating internal state

Description

The emergencyWithdraw function in BaseGauge allows admin to withdraw any token, including the staking token, without updating internal accounting:

function emergencyWithdraw(address token, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
IERC20(token).safeTransfer(msg.sender, amount); // @audit withdraws tokens without state update
}
// Other contract state
uint256 private _totalSupply; // Total staked amount
mapping(address => uint256) private _balances; // User balances

This creates a critical state inconsistency:

  1. Admin can withdraw staking tokens

  2. Internal accounting (_totalSupply, _balances) remains unchanged

  3. Future user withdrawals will fail due to insufficient contract balance

  4. Reward calculations become incorrect as they rely on totalSupply()

It has High impact:

  • Users unable to withdraw staked tokens

  • Incorrect reward distributions due to wrong totalSupply

  • Permanent desync between real and recorded balances

Recommendation

Either prevent withdrawal of staking token:

function emergencyWithdraw(address token, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(token != address(stakingToken), "Cannot withdraw staking token");
IERC20(token).safeTransfer(msg.sender, amount);
}

Or update state when withdrawing staking token:

function emergencyWithdraw(address token, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
if(token == address(stakingToken)) {
require(amount <= _totalSupply, "Amount exceeds total supply");
_totalSupply -= amount;
// Update affected user balances or prevent new staking/withdrawals
emit EmergencyWithdrawalStateUpdate(_totalSupply);
}
IERC20(token).safeTransfer(msg.sender, amount);
}
Updates

Lead Judging Commences

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