Core Contracts

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

Emergency Unlock Logic Incomplete

Author Revealed upon completion

Summary

function executeEmergencyUnlock() external onlyOwner withEmergencyDelay(EMERGENCY_UNLOCK_ACTION) {
emergencyUnlockEnabled = true;
emit EmergencyUnlockEnabled();
}

The veRAACToken contract includes functions to schedule and execute an emergency unlock mechanism (scheduleEmergencyUnlock and executeEmergencyUnlock), but setting emergencyUnlockEnabled = true currently has no further effect. Users and project owners may assume that once the emergency unlock is enabled, locked tokens can be immediately withdrawn or other emergency actions are available; however, there is no corresponding code that actually bypasses the standard lock restrictions.

Vulnerability Details

Missing Integration: Although emergencyUnlockEnabled is set to true upon calling executeEmergencyUnlock, it is never referenced or checked anywhere else in the contract. Consequently, no behavior changes when the variable is toggled.

Potential Misconfiguration: If the project’s design requires an emergency unlock to allow withdrawals before the lock end, that functionality is incomplete. The absence of conditions in withdraw() or other relevant functions means that the lock period remains enforced regardless of the emergency unlock flag.

False Sense of Security: Owners and users might incorrectly assume that the emergency mechanism will allow early unlocking of tokens, leading to unexpected outcomes in an actual emergency.

Impact

Inoperative Emergency Feature: During a real crisis (e.g., security breach, protocol migration), stakeholders could be unable to unlock their tokens prematurely if they rely on this flag.

Reputation and Trust: The contract claims to provide an emergency unlock mechanism, but its partial implementation can erode trust if it fails to operate as expected.

Implementation Risk: If left unaddressed, this incomplete feature might be exploited or remain a source of confusion in the future code updates or audits.

Tools Used

Manual Code Review: Carefully examined the emergency unlock workflow and traced how the emergencyUnlockEnabled variable is set and used throughout the contract.

Recommendations

function withdraw() external nonReentrant {
LockManager.Lock memory userLock = _lockState.locks[msg.sender];
-
if (userLock.amount == 0) revert LockNotFound();
- if (block.timestamp < userLock.end) revert LockNotExpired();
+
+ // If emergency unlock is not enabled, enforce the normal lock expiry
+ if (!emergencyUnlockEnabled) {
+ if (block.timestamp < userLock.end) revert LockNotExpired();
+ }
uint256 amount = userLock.amount;
uint256 currentPower = balanceOf(msg.sender);
// Clear lock data
delete _lockState.locks[msg.sender];
delete _votingState.points[msg.sender];
// Update checkpoints
_checkpointState.writeCheckpoint(msg.sender, 0);
// Burn veTokens and transfer RAAC
_burn(msg.sender, currentPower);
raacToken.safeTransfer(msg.sender, amount);
emit Withdrawn(msg.sender, amount);
}
@@ -280,6 +290,11 @@ contract veRAACToken is ERC20, Ownable, ReentrancyGuard, IveRAACToken {
*/
function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
+ // (Example) Disallow creating new locks if emergency unlock is active
+ if (emergencyUnlockEnabled) {
+ revert("Cannot create new locks during emergency unlock");
+ }
+
if (amount == 0) revert InvalidAmount();
if (amount > MAX_LOCK_AMOUNT) revert AmountExceedsLimit();
if (totalSupply() + amount > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();

1. Implement Emergency Unlock Checks:

• In withdraw() or in a dedicated function, add logic that allows locked tokens to be withdrawn if emergencyUnlockEnabled is true. This should override normal lock expiration checks.

2. Remove Unused Code If Not Needed:

• If the project no longer requires an emergency unlock feature, remove the scheduling and execution functions as well as emergencyUnlockEnabled to avoid confusion.

3. Document Intended Behavior:

• Clearly specify in the contract’s documentation or README how the emergency unlock is expected to work, including any constraints or trade-offs (e.g., penalty fees, partial unlock).

4. Add Tests for Emergency Scenarios:

• Ensure that unit tests confirm the emergency unlock process correctly bypasses lock constraints once enabled, and that scheduling remains subject to the timelock.

By addressing these points, the emergency unlock logic will either function as intended or be removed altogether, thereby reducing confusion and potential misinterpretation of the contract’s capabilities.

Updates

Lead Judging Commences

inallhonesty Lead Judge 8 days ago
Submission Judgement Published
Validated
Assigned finding tags:

veRAACToken::executeEmergencyUnlock is dormant, it configures a system that's never used

Support

FAQs

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