The emergencyRevoke() function allows an authorized user to revoke a vesting schedule. However, since this action is a transaction on-chain, a beneficiary can monitor pending transactions and front-run the revocation by calling release() to claim their vested tokens before the revocation executes. This allows them to withdraw their entitled amount before the emergency action takes effect, potentially undermining the purpose of the revocation.
The contract includes an emergencyRevoke(address beneficiary) function, callable by the EMERGENCY_ROLE, which deletes a vesting schedule and transfers unclaimed tokens back to the contract.
The release() function allows a beneficiary to withdraw their vested tokens if available.
There is no mechanism to prevent a beneficiary from calling release() right before emergencyRevoke() executes.
Since blockchain transactions are public before execution, a malicious beneficiary can detect an emergency revocation in the mempool and prioritize their release() transaction by increasing the gas fee.
If successful, they withdraw their vested tokens before the revocation takes effect, making the revocation less effective.
Beneficiaries Can Bypass Revocation: A beneficiary can drain their available vested tokens before revocation occurs, reducing the amount recovered by the contract.
Potential Financial Loss: If revocation is intended to stop further claims in emergencies (e.g., fraud, misallocation), a malicious actor could escape with more tokens than intended.
Manual Code Review
Perform Revocation in Two Steps
Step 1: Mark the beneficiary as revoked and block withdrawals immediately.
Step 2: In a separate transaction, execute the actual token recovery.
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.