The Stargate.sol contract allows a delegation that has already exited and fully claimed all legitimate rewards up to its endPeriod to continue claiming VTHO rewards for later staking periods, where it should no longer be entitled to anything. Because the per-period reward share is computed using a token’s full effective stake but the total delegators’ effective stake no longer includes that token, an attacker can indefinitely siphon extra VTHO yield, causing systematic overpayment of rewards and direct loss of unclaimed yield from the protocol and/or honest delegators.
Vulnerability Details
When a delegation exits, the protocol sets a finite endPeriod for that delegation. After that period, the NFT should no longer earn rewards. However, Stargate.sol's period-selection logic allows an exited NFT to keep accruing rewards for periods strictly after endPeriod.
Looking at the _claimableDelegationPeriods function:
Suppose the delegation has already claimed all rewards up to its last valid period endPeriod, then lastClaimedPeriod[_tokenId] = endPeriod; so, nextClaimablePeriod = endPeriod + 1. And as the validator continues operating, completedPeriods increases so that completedPeriods > endPeriod and currentValidatorPeriod = completedPeriods + 1.
In this state, the 'ended delegation' branch requires endPeriod > nextClaimablePeriod, which is false, so that branch is skipped. The fallback 'active' branch sees nextClaimablePeriod < currentValidatorPeriod as true, and returns firstClaimablePeriod = endPeriod + 1 and lastClaimablePeriod = completedPeriods.
So, after all legitimate periods up to endPeriod have been claimed, _claimableDelegationPeriods starts returning new claimable periods strictly greater than endPeriod, even though the delegation has ended.
Impact Details
Any regular user who has delegated once can delegate an NFT to a validator and earn rewards normally, call requestDelegationExit while the delegation is active, setting a finite endPeriod, claim all legitimate rewards up to endPeriod and as the validator continues to earn delegator rewards for subsequent periods, repeatedly call claimRewards to receive additional VTHO for periods > endPeriod, where they should not participate.
This occurs because, in the _claimableRewardsForPeriod function, the numerator uses the exited NFT’s full effective stake, while the denominator excludes that stake from the validator’s total delegators’ effective stake for those periods.
The following PoC is a Hardhat unit test that reproduces the issue.
1
Overview — sequence of actions reproduced by the test
Attacker stakes an NFT and delegates it to a validator; an honest delegator does the same to the same validator.
Fast-forward periods so both delegations become ACTIVE and rewards accrue.
Attacker requests exit while ACTIVE, setting a finite endPeriod. After one more completed period, the delegation becomes EXITED.
Attacker legitimately claims all rewards up to endPeriod.
Advance many more periods; the exited attacker delegation remains in status EXITED.
BUG: the exited delegator gets NEW claimable periods (strictly after endPeriod) and can claim VTHO for them, receiving tokens that they should not be eligible for.
Full test file (place at packages/contracts/test/unit/Stargate/ExitedDelegationRewards.PoC.test.ts):
To run the test:
Place the file at packages/contracts/test/unit/Stargate/ExitedDelegationRewards.PoC.test.ts
cd packages/contracts
npx hardhat test test/unit/Stargate/ExitedDelegationRewards.PoC.test.ts