The RAACReleaseOrchestrator contract imports SafeERC20 but does not use its safe wrappers when releasing vested tokens or during emergency revocation. In the functions:
release()
Tokens are transferred via:
emergencyRevoke()
Unreleased tokens are transferred via:
Because the return values of these calls are not checked and the safe wrappers are not used, if the RAAC token implementation deviates from the ERC20 standard (for example, returning false on failure rather than reverting), the transfer may silently fail. This causes the contract’s internal state (which is updated before the transfer) to be inconsistent with the actual token balances—beneficiaries may have their vesting state advanced while not receiving tokens.
An attacker (or a faulty token implementation) provides a RAAC token that returns false on a transfer instead of reverting.
Beneficiary Releases Vested Tokens:
The beneficiary calls the release() function.
The contract calculates a positive releasable amount, updates the vesting schedule (increasing releasedAmount and updating lastClaimTime), and then calls raacToken.transfer(beneficiary, releasableAmount).
Because the token’s transfer returns false (without reverting), the transfer fails silently.
Resulting Impact:
The beneficiary’s vesting schedule is updated as if tokens were delivered, but their token balance remains unchanged. This “lost transfer” can lead to locked or misallocated funds.
Below is a professional Foundry test that demonstrates the issue:
The MaliciousRAACToken contract overrides the standard transfer function to always return false, simulating a non-compliant token that fails silently.
Test Flow:
A vesting schedule is created for a beneficiary with a start time long enough to overcome the vesting cliff.
The beneficiary calls release(). Although the contract’s internal state (i.e. releasedAmount) is updated, the transfer call fails silently.
The test confirms that the beneficiary’s balance remains zero even though the vesting schedule shows tokens as “released.”
Fix:
Replace all instances of:
with:
This change leverages SafeERC20’s wrappers to ensure that token transfers revert on failure, preventing the internal state from diverging from the actual token balances.
LightChaser Low-60
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.