Core Contracts

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

`RAACReleaseOrchestrator::emergencyRevoke()` performs meaningless token transfer

Summary

The RAACReleaseOrchestrator::emergencyRevoke() function performs an unnecessary token transfer, sending tokens from the contract to itself, which has no effect on the token balance but incurs unnecessary gas costs.

Vulnerability Details

As indicated by the @> mark in the code, the contract executes a token transfer where the recipient is address(this), meaning the contract is transferring tokens to itself. This operation serves no functional purpose.

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 contract calls raacToken.transfer(address(this), unreleasedAmount);, effectively transferring tokens from itself to itself.
In standard ERC-20 implementations, the transfer function typically follows this logic:

require(balanceOf[msg.sender] >= amount, "Insufficient balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);

Since msg.sender == address(this), the function will deduct the contract’s balance and then immediately add the same amount back, resulting in no actual change in token ownership.
Despite having no functional impact, the operation still consumes gas, making it an entirely redundant transaction.

Impact

The unnecessary token transfer wastes gas without achieving any meaningful result.
While it does not directly affect contract functionality, it introduces inefficiencies in transaction execution.

Tools Used

Manual Review

Recommendations

Remove or replace raacToken.transfer(address(this), unreleasedAmount); with a meaningful operation, such as redistributing or reallocating the revoked tokens if needed.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month 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 about 1 month 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.