The emergencyRevoke() function in RAACReleaseOrchestrator incorrectly transfers unreleased tokens to the contract itself instead of the beneficiary, resulting in permanent token loss.
In the emergencyRevoke function, when revoking a vesting schedule, any unreleased tokens are meant to be returned to the beneficiary. However, the function incorrectly uses address(this) as the transfer recipient instead of the beneficiary address:
A vesting schedule is created for Alice with 1000 RAAC tokens
After 100 days, Alice has claimed 200 tokens, leaving 800 unreleased
Emergency role calls emergencyRevoke for Alice's address
Instead of sending the 800 tokens to Alice, they are transferred to the contract itself
The tokens become permanently locked in the contract as there is no function to withdraw them
Beneficiaries lose their unreleased tokens when their vesting schedule is revoked
Tokens become permanently locked in the contract
The emergency revoke feature fails its intended purpose of returning tokens to beneficiaries
Consider removing the emergency revoke functionality entirely if it's not strictly necessary, as it introduces additional risk and complexity. The vesting schedule could be made immutable after creation.
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.