Core Contracts

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

EmergencyRevoke Doesn’t Update categoryUsed, Permanently Locking Vesting Allocations

Summary

The emergencyRevoke function in RAACReleaseOrchestrator contract does not update categoryUsed, causing revoked tokens to remain accounted for in the category usage. This leads to incorrect allocation tracking, making it impossible to allocate new vesting schedules even when tokens should be available.

Vulnerability Details

When a vesting schedule is revoked, the contract deletes the schedule but does not update categoryUsed. Since categoryUsed continues to count revoked tokens, new schedules cannot be created under the same category even if the tokens should be available.

Affected Code

emergencyRevoke()

Initial Setup

  • PRIVATE_SALE allocation: 10,000,000 RAAC

  • Used before transactions: 8,000,000 RAAC

  • Remaining: 2,000,000 RAAC

Step 1: Freddie Allocates to Ummi

  • Freddie (admin) vests 2,000,000 RAAC to Ummi (investor).

  • PRIVATE_SALE allocation is now fully used (10,000,000 RAAC).

Step 2: Freddie Revokes Ummi’s Vesting

  • One year later, Ummi has claimed 500,000 RAAC.

  • Freddie revokes the remaining 1,500,000 RAAC.

  • categoryUsed remains 10,000,000 instead of updating to 8,500,000.

Step 3: Dan's Vesting Fails

  • Freddie attempts to vest 1,500,000 RAAC to Dan (new investor).

  • The transaction fails with "CategoryAllocationExceeded" error.

  • The contract incorrectly treats PRIVATE_SALE as fully used, preventing new allocations.

Impact

  • Incorrect Allocation Tracking: The total available allocation per category is misrepresented.

  • Denial of Future Vesting Schedules: Future vesting schedules will be incorrectly blocked due to the overestimated usage.

  • Inefficient Token Utilization: The inability to properly reclaim allocation will lead to funds being locked or unused.

  • this also make *getCategoryDetails() *returns a false representation of categoryUsed, making it unreliable for tracking allocation status.

    Note : This flaw effectively reduces the total allocatable supply of RAAC tokens over time as revoked allocations become unusable, directly conflicting with the token's distribution plan (65% allocated for vesting)

Tools Used

Manual Review

Recommendations

1 - Store the vesting category within VestingSchedule for reference.

2 - Reduce categoryUsed upon revocation to accurately track available allocations.

struct VestingSchedule {
uint256 totalAmount;
uint256 releasedAmount;
uint256 startTime;
uint256 duration;
bool initialized;
+ bytes32 category; // Store category for reference
}
function createVestingSchedule(
address beneficiary,
bytes32 category,
uint256 amount,
uint256 startTime
) external onlyRole(ORCHESTRATOR_ROLE) whenNotPaused {
...
+ schedule.category = category; // Store category in the struct
}
function emergencyRevoke(address beneficiary) external onlyRole(EMERGENCY_ROLE) {
VestingSchedule storage schedule = vestingSchedules[beneficiary];
if (!schedule.initialized) revert NoVestingSchedule();
uint256 unreleasedAmount = schedule.totalAmount - schedule.releasedAmount;
+ categoryUsed[schedule.category] -= unrealeasedAmount; // Adjust category usage
delete vestingSchedules[beneficiary];
if (unreleasedAmount > 0) {
raacToken.transfer(address(this), unreleasedAmount);
emit EmergencyWithdraw(beneficiary, unreleasedAmount);
}
emit VestingScheduleRevoked(beneficiary);
}
Updates

Lead Judging Commences

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

RAACReleaseOrchestrator::emergencyRevoke fails to decrement categoryUsed, causing artificial category over-allocation and rejection of valid vesting schedules

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

RAACReleaseOrchestrator::emergencyRevoke fails to decrement categoryUsed, causing artificial category over-allocation and rejection of valid vesting schedules

Support

FAQs

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