Core Contracts

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

Unreleased RAAC Tokens Permanently Locked in Contract After Emergency Revoke

Summary

The emergencyRevoke function in the RAACReleaseOrchestrator contract revokes a beneficiary’s vesting schedule and removes their vesting record. However, the function transfers the unreleased RAAC tokens to the contract’s own address instead of reassigning or redistributing them. Since the contract does not have a function to withdraw these tokens, they become permanently locked, making them inaccessible to any entity.

Vulnerability Details

RAACReleaseOrchestrator:: emergencyRevoke

/**
* @notice Emergency revoke of vesting schedule
* @param beneficiary Address of the beneficiary to revoke
* @dev Only callable by EMERGENCY_ROLE - Do we really want to allow this in the first place, would need more move too ?
*/
function emergencyRevoke(
address beneficiary
) external onlyRole(EMERGENCY_ROLE) {
VestingSchedule storage schedule = vestingSchedules[beneficiary];
if (!schedule.initialized) revert NoVestingSchedule();
uint256 unreleasedAmount = schedule.totalAmount -
schedule.releasedAmount;
delete vestingSchedules[beneficiary];
if (unreleasedAmount > 0) {
@> raacToken.transfer(address(this), unreleasedAmount);
emit EmergencyWithdraw(beneficiary, unreleasedAmount);
}
emit VestingScheduleRevoked(beneficiary);
}
  • The function emergencyRevoke retrieves the unreleasedAmount (i.e., totalAmount - releasedAmount) of a beneficiary.

  • The function deletes the vesting schedule for that beneficiary.

  • It then transfers the unreleasedAmount to the contract’s own address (address(this)).

  • The contract does not implement a mechanism to reclaim or redistribute these locked tokens.

  • Since release() depends on vestingSchedules[beneficiary], and the vesting schedule has been deleted, the beneficiary loses access to their tokens.

This results in a permanent loss of the revoked tokens, as they remain inaccessible within the contract.

Impact

Unreleased RAAC tokens will be permanently locked in the contract. The total supply of circulating RAAC tokens will be reduced.

Tools Used

Manual

Recommendations

Instead of transferring the tokens to the contract, consider transferring them to a designated treasury or an administrator address. Or implement a function to recover and redistribute revoked tokens.

Updates

Lead Judging Commences

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

RAACReleaseOrchestrator::emergencyRevoke sends revoked tokens to contract address with no withdrawal mechanism, permanently locking funds

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

RAACReleaseOrchestrator::emergencyRevoke sends revoked tokens to contract address with no withdrawal mechanism, permanently locking funds

Support

FAQs

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