Core Contracts

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

Emergency Revocation with Partial Vesting

Description

When a beneficiary has partially vested tokens, the emergency revocation process does not correctly handle the remaining amount after some tokens have been released. This can lead to incorrect tracking of category allocations.

Code Analysis

In the same emergencyRevoke function, the following logic is executed:

uint256 unreleasedAmount = schedule.totalAmount - schedule.releasedAmount;
delete vestingSchedules[beneficiary];

Issues Identified:

  • Failure to Update Category Usage: The categoryUsed mapping is not updated to reflect the amount that has been released. This means that the total used allocation for the category remains unchanged, which can lead to incorrect tracking of category allocations and potentially prevent future allocations from being made.

  • Potential Loss of Funds: If the revocation occurs after some tokens have been released, the contract does not account for the fact that the released tokens should not be considered part of the unreleasedAmount. This could lead to a situation where the contract attempts to manage tokens that are no longer available.

Reported Issue

When a beneficiary has partially vested tokens, the emergency revocation process does not correctly handle the remaining amount after some tokens have been released. This can lead to incorrect tracking of category allocations.

Analysis

The emergencyRevoke function does the following:

  1. Calculates the unreleasedAmount as schedule.totalAmount - schedule.releasedAmount.

  2. Deletes the vesting schedule.

  3. Transfers the unreleasedAmount back to the contract.

Key Observations:

  • The categoryUsed mapping is not updated when a vesting schedule is revoked. This is a valid concern, as the categoryUsed value should be reduced by the unreleasedAmount to reflect the fact that these tokens are no longer allocated to the beneficiary.

  • The unreleasedAmount calculation itself is correct, as it accounts for the tokens already released (schedule.releasedAmount).

  • The contract does not lose funds, as the unreleasedAmount is transferred back to the contract. However, the categoryUsed mapping becomes inaccurate because it does not reflect the reduction in allocated tokens.

Conclusion

This issue is valid. The emergencyRevoke function fails to update the categoryUsed mapping when revoking a vesting schedule. This can lead to incorrect tracking of category allocations, potentially preventing future allocations even when tokens are available.


Recommendations

To fix the valid issue (incorrect tracking of category allocations), update the emergencyRevoke function to reduce the categoryUsed value for the corresponding category. Here's the corrected code:

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];
// Update categoryUsed to reflect the reduction in allocated tokens
bytes32 category = schedule.category; // Assuming category is stored in the schedule
categoryUsed[category] -= unreleasedAmount;
if (unreleasedAmount > 0) {
raacToken.transfer(address(this), unreleasedAmount);
emit EmergencyWithdraw(beneficiary, unreleasedAmount);
}
emit VestingScheduleRevoked(beneficiary);
}

Changes Made:

  1. Added a line to reduce the categoryUsed value for the corresponding category by the unreleasedAmount.

  2. Assumed that the category is stored in the VestingSchedule struct. If it is not, you will need to modify the createVestingSchedule function to store the category in the schedule.


Emergency Revocation with Partial Vesting: Confirmed. The categoryUsed mapping is not updated, leading to incorrect tracking of category allocations. This should be fixed as described above.

Updates

Lead Judging Commences

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