Because BoostController only checks the user’s veRAAC balance once at the moment of delegateBoost(...) and never re-checks or revokes if the user’s balance declines, users can exploit the system by delegating a large amount and then withdrawing veRAAC. The delegated “boost” remains valid for the entire duration, awarding unbacked benefits. Ensuring synergy (re-check or forcibly reduce delegations) is essential to preserve the protocol’s intended “boost” design and ensure the user’s delegation remains properly collateralized by their actual veRAAC holdings.
delegateBoost(...) in BoostController
The user calls:
This sets UserBoost with amount and an expiry, effectively guaranteeing that “X” units of veRAAC are delegated for that duration.
No Ongoing Balance Check
Once set, the BoostController never re‑checks whether the user still has that many veRAAC tokens locked in veRAACToken. The contract only checks the user’s balance at the moment of delegation (via if (userBalance < amount) revert InsufficientVeBalance()).
User Reduces or Withdraws veRAAC
Right after delegating, the user calls:
or does any action that drastically lowers their veRAAC balance. The BoostController is not notified. The delegation stays in userBoosts[from][to] with the same amount.
Inflated or Undeserved Boost
The delegate (or the pool that sees the delegated boost) continues to receive the full “amount” for the entire “duration,” even though the user’s backing veRAAC is now partial or zero. Essentially, the system is awarding a boost that is no longer collateralized by any real veTokens.
Cheating the “Boost” Mechanic
The protocol typically requires a user to hold veTokens in order to secure a delegation or boost. By withdrawing or reducing the underlying tokens right after delegation, the user (or the beneficiary) keeps an unbacked delegation for the entire “duration.”
Distorted Governance/Yield
If the delegated boost influences yield distribution, gauge weight, or other “boosted” rewards, the system grants that delegation undeservedly—leading to higher rewards than the user’s real veBalance would justify.
Lack of Cross‑Module Integrity
The code never revokes or updates the delegated boost if the user’s veRAAC holdings vanish. That breaks typical synergy expectations in which delegations must reflect the user’s real, continuing lock of veTokens.
Attack / PoC Example
User Has 1,000 veRAAC
Calls delegateBoost(beneficiary, 800, 30 days) in BoostController.
BoostController checks userBalance >= 800—passes.
The delegation is set with amount=800, expiry = block.timestamp + 30 days.
User Immediately Withdraws
The user calls veRAACToken.withdraw() or modifies their lock, reducing their veRAAC from 1,000 to 0 (or 100, etc.). The BoostController never sees or checks this event.
Beneficiary Gains Full Boost
The “beneficiary” or the pool sees the full 800 “boost” for the next 30 days, even though the delegator only holds 0 or minimal veRAAC.
No function re-checks or slashes the delegation.
Continuous Validation
In BoostController, each time the user’s veBalance changes, re-check the delegation. If the user no longer meets the “amount,” reduce or cancel the delegation. This can be done by hooking into veRAACToken events or by requiring an “update” call.
Frequent “Delegation Renewal”
Instead of a set “duration,” require the user to maintain the lock or re-commit the delegation periodically. If they remove the lock, the delegation automatically ends or is forcibly updated.
Explicit Revocation If Under-Collateralized
Each call to updateUserBoost(...), removeBoostDelegation(...), or an admin function can forcibly revoke any delegations that exceed the user’s current veRAAC balance.
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.