Summary
The RAACReleaseOrchestrator
contract allows updating category allocations without enforcing the 65% total supply limit specified in the contract's design. This could lead to over-allocation of tokens beyond the intended distribution scheme.
Vulnerability Details
[](https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/minters/RAACReleaseOrchestrator/RAACReleaseOrchestrator.sol#L16)
[](https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/minters/RAACReleaseOrchestrator/RAACReleaseOrchestrator.sol#L147-L154)
The contract is designed to handle 65% of the total token supply, split across different categories as stated in the natspec and initial set shares:
* @dev Implements vesting schedules for initial token distribution (65% of total supply)
categoryAllocations[TEAM_CATEGORY] = 18_000_000 ether;
categoryAllocations[ADVISOR_CATEGORY] = 10_300_000 ether;
categoryAllocations[TREASURY_CATEGORY] = 5_000_000 ether;
categoryAllocations[PRIVATE_SALE_CATEGORY] = 10_000_000 ether;
categoryAllocations[PUBLIC_SALE_CATEGORY] = 15_000_000 ether;
categoryAllocations[LIQUIDITY_CATEGORY] = 6_800_000 ether;
However, the updateCategoryAllocation
function lacks a check to ensure that changes to category allocations don't exceed this limit:
function updateCategoryAllocation(
bytes32 category,
uint256 newAllocation
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (categoryAllocations[category] == 0) revert InvalidCategory();
if (newAllocation < categoryUsed[category]) revert InvalidAmount();
categoryAllocations[category] = newAllocation;
emit CategoryAllocationUpdated(category, newAllocation);
}
The contract already has a getTotalAllocation()
function that could be used for this check, but it's not being utilized:
function getTotalAllocation() external view returns (uint256 total) {
return categoryAllocations[TEAM_CATEGORY] +
categoryAllocations[ADVISOR_CATEGORY] +
categoryAllocations[TREASURY_CATEGORY] +
categoryAllocations[PRIVATE_SALE_CATEGORY] +
categoryAllocations[PUBLIC_SALE_CATEGORY] +
categoryAllocations[LIQUIDITY_CATEGORY];
}
Impact
Categories or total sum of Categories could be allocated more than the intended 65% of total supply
Violates core tokenomics design of the protocol
Could lead to excess token distribution if not caught
Tools Used
Manual code review
Recommendations
Add a check in updateCategoryAllocation
to ensure the total allocation doesn't exceed 65% of total supply:
function updateCategoryAllocation(
bytes32 category,
uint256 newAllocation
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (categoryAllocations[category] == 0) revert InvalidCategory();
if (newAllocation < categoryUsed[category]) revert InvalidAmount();
+ // 65% of total supply = 65_000_000 ether
+ if (getTotalAllocation() > 65_000_000 ether) revert ExceedsTotalAllocationLimit();
categoryAllocations[category] = newAllocation;
emit CategoryAllocationUpdated(category, newAllocation);
}