When a beneficiary's vesting schedule is revoked using emergencyRevoke, the unreleased tokens are permanently locked in the contract and become unusable. This occurs because the tokens have already been accounted for in categoryUsed[category], but there is no mechanism to recycle them back into the vesting system or allocate them elsewhere.
The function emergencyRevoke deletes the vesting schedule of the beneficiary.
The unreleasedAmount of tokens (i.e., tokens that have not yet been claimed) is calculated but not reassigned to a valid category or beneficiary.
Instead, the contract attempts to transfer the tokens to itself:
Since categoryUsed[category] is not decremented, the locked tokens cannot be reassigned or reallocated.
The inability to recycle tokens leads to permanent token loss because of the following constraint in createVestingSchedule:
categoryUsed[category] continues to count revoked allocations, so even though tokens are no longer assigned to a beneficiary, they cannot be reallocated and cannot be called `release()` on
If an admin tries to create a new vesting schedule, the CategoryAllocationExceeded check will fail because the system believes the tokens are still used.
Over time, as revocations occur, more and more tokens will be permanently locked, reducing the available supply for vesting and causing misalignment between intended allocations and actual token distribution.
Unreleased tokens are permanently locked inside the contract, reducing the total circulating supply.
The vesting schedule cannot be properly adjusted if a revocation is necessary.
Future beneficiaries may not receive their intended allocations due to artificial allocation caps.
Manual code review
Instead of transferring tokens to the contract, decrement categoryUsed[category] to allow the tokens to be reassigned:
Alternatively, allow an admin function to reallocate revoked tokens to a new beneficiary.
Consider allowing a recovery mechanism where unreleased tokens are returned to the treasury or another predefined category.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.