59776 sc high exited delegators can over claim vtho rewards for post exit periods due to off by one error in claimabledelegationperiods
Submitted on Nov 15th 2025 at 17:38:20 UTC by @jayx for Audit Comp | Vechain | Stargate Hayabusa
Report ID: #59776
Report Type: Smart Contract
Report severity: High
Target: https://github.com/immunefi-team/audit-comp-vechain-stargate-hayabusa/tree/main/packages/contracts/contracts/Stargate.sol
Impacts: Theft of unclaimed yield
Description
Brief / Intro
The Stargate contract contains an off‑by‑one error in _claimableDelegationPeriods that allows users who have exited a delegation to continue claiming VTHO rewards for validator periods that occurred after their delegation ended.
When a delegation's endPeriod equals the user's next claimable period, the "ended" branch condition (endPeriod > nextClaimablePeriod) evaluates to false and the function falls through to the "active" branch, incorrectly returning the validator's latest completed period as the last claimable period. This lets ex‑delegators drain rewards that should remain in the pool for currently active delegators, resulting in theft of unclaimed yield and unfair distribution of protocol rewards.
Vulnerability Details
The root cause lies in the _claimableDelegationPeriods function of Stargate.sol.
Current implementation (relevant excerpt):
if (
endPeriod != type(uint32).max &&
endPeriod < currentValidatorPeriod &&
endPeriod > nextClaimablePeriod // ❌ Bug: Excludes equality case
) {
return (nextClaimablePeriod, endPeriod); // ✅ Correct cap at endPeriod
}
// Falls through to "active" branch
if (nextClaimablePeriod < currentValidatorPeriod) {
return (nextClaimablePeriod, completedPeriods); // ❌ Inflated: Includes post-exit periods
}The problem is the strict inequality endPeriod > nextClaimablePeriod. Consider this scenario:
The correct condition should be endPeriod >= nextClaimablePeriod to ensure that when endPeriod equals nextClaimablePeriod, the function caps the window at endPeriod and does not expose later periods.
This bug is amplified because claimRewards calls _claimableDelegationPeriods internally, and the calculated window is used directly to compute VTHO transfers:
Since the loop iterates inclusive of lastClaimablePeriod, the inflated lastClaimablePeriod directly results in excess VTHO being transferred to the ex‑delegator.
Impact Details
This vulnerability enables theft of unclaimed yield from the protocol's VTHO reward pool, with these consequences:
Direct financial loss: Ex‑delegators can claim VTHO rewards for periods during which they were no longer delegating, stealing yield that should either remain in the pool or be distributed to currently active delegators. Over multiple periods and users, the drain can be significant.
Unfair reward distribution: Active delegators receive proportionally less reward because a portion of each period's rewards is being siphoned by ex‑delegators who are no longer participating. This breaks the protocol's economic guarantees.
References
https://github.com/immunefi-team/audit-comp-vechain-stargate-hayabusa/blob/e9c0bc9b0f24dc0c44de273181d9a99aaf2c31b0/packages/contracts/contracts/Stargate.sol#L916C8-L930C10
Proof of Concept
The test below reproduces the current (buggy) behavior. It performs delegation, claims once, requests exit, advances validator completed periods, and then observes that an ex‑delegator can still claim for periods after their endPeriod.
Suggested fix: change the condition to endPeriod >= nextClaimablePeriod so the delegation's endPeriod properly caps the claimable window when equal to nextClaimablePeriod.
Was this helpful?