Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

Delegated Boost Persists Even If veRAAC Is Withdrawn/Reduced

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/boost/BoostController.sol#L212

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.

Overview

  1. delegateBoost(...) in BoostController
    The user calls:

    function delegateBoost(address to, uint256 amount, uint256 duration) external {
    // checks userBalance >= amount
    delegation.amount = amount;
    delegation.expiry = block.timestamp + duration;
    ...
    }

    This sets UserBoost with amount and an expiry, effectively guaranteeing that “X” units of veRAAC are delegated for that duration.

  2. 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()).

  3. User Reduces or Withdraws veRAAC
    Right after delegating, the user calls:

    veRAACToken.withdrawNFT(tokenId); // or reduce the lock

    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.

  4. 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.

Impact

  • 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

  1. 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.

  2. 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.

  3. 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.

Recommendation

  1. 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.

  2. 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.

  3. 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.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BoostController delegations remain valid even when users withdraw their veRAAC tokens, allowing boost "double-spending" and undermining the economic model requiring locked tokens

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BoostController delegations remain valid even when users withdraw their veRAAC tokens, allowing boost "double-spending" and undermining the economic model requiring locked tokens

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!