For the complete documentation index, see llms.txt. This page is also available as Markdown.

60192 sc high users can claim delegation rewards after exit endperiod has passed

Submitted on Nov 19th 2025 at 18:41:47 UTC by @Rhaydden for Audit Comp | Vechain | Stargate Hayabusa

  • Report ID: #60192

  • 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

A logic gap in Stargate’s reward claim window computation allows a token to claim delegation rewards for periods after its delegation has ended.

In Stargate.sol::_claimableDelegationPeriods, the delegation ended branch only triggers when endPeriod > nextClaimablePeriod. If nextClaimablePeriod >= endPeriod, the code falls through to the active/past branch and returns the current completed periods, effectively green-lighting claims for periods strictly after endPeriod.

Stargate.sol:

// Lines ~916-930
if (
    endPeriod != type(uint32).max &&
    endPeriod < currentValidatorPeriod &&
    endPeriod > nextClaimablePeriod
) {
    return (nextClaimablePeriod, endPeriod);
}

// check that the start period is before the current validator period
if (nextClaimablePeriod < currentValidatorPeriod) {
    return (nextClaimablePeriod, completedPeriods);
}

When nextClaimablePeriod == endPeriod: this should clamp to endPeriod, but if the user had already claimed through endPeriod, nextClaimablePeriod becomes endPeriod + 1 and the function returns a range that includes periods after endPeriod.

When nextClaimablePeriod > endPeriod (exhausted): the function still falls through and returns (nextClaimablePeriod, completedPeriods).

Finding description and impact

Exited delegators can claim rewards for a period in which they were no longer delegated. This is a direct transfer of unclaimed yield from active delegators to an ex-delegator.

High - Theft of unclaimed yield

Consider a scenario where:

  • User delegates at period 1 and requests exit at period 3 (endPeriod = 3).

  • User claims up to period 3 (so lastClaimedPeriod = 3).

  • Later, validator advances to period 5.

  • The function returns (4, 4) as claimable periods for the user, allowing a claim for period 4 even though the delegation ended at period 3.

Clamp strictly when the delegation has ended, and guard the exhausted case:

Proof of concept

Created a test file packages/contracts/test/unit/Stargate/PostExitClaimPoC.test.ts demonstrating a token claiming rewards for a period after its delegation ended.

TypeScript/Hardhat test used as PoC:

Run command used:

VITE_APP_ENV=local yarn workspace @repo/contracts hardhat test --network hardhat test/unit/Stargate/PostExitClaimPoC.test.ts

Logs

Was this helpful?