60265 sc high the attacker can still claim rewards after exiting from validator

Submitted on Nov 20th 2025 at 17:38:12 UTC by @aman for Audit Comp | Vechain | Stargate Hayabusaarrow-up-right

  • Report ID: #60265

  • 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

When a delegator exits a validator, they are expected to stop earning rewards after the exit period. However, this core restriction does not function as intended, and users are still able to claim rewards even after their delegation exit period has passed.

Vulnerability Details

In scenarios where the validator is still active and a delegator calls requestDelegationExit, the delegator is not removed immediately from the validator. Instead, the removal only takes effect after the next period, meaning the delegator remains active until then. This behavior can be observed in the following code snippet:

/audit-comp-vechain-stargate-hayabusa/packages/contracts/contracts/Stargate.sol:523
523:     function requestDelegationExit(
524:         uint256 _tokenId
525:     ) external whenNotPaused onlyTokenOwner(_tokenId) nonReentrant {
526:         StargateStorage storage $ = _getStargateStorage();
527:         uint256 delegationId = $.delegationIdByTokenId[_tokenId];
...
547:         } else if (delegation.status == DelegationStatus.ACTIVE) {
548:             // If the delegation is active, we need to signal the exit to the protocol and wait for the end of the period
549: 
550:             // We do not allow the user to request an exit multiple times
551:             if (delegation.endPeriod != type(uint32).max) {
552:                 revert DelegationExitAlreadyRequested();
553:             }
554: 
555:             $.protocolStakerContract.signalDelegationExit(delegationId);
556:         } else {
557:             revert InvalidDelegationStatus(_tokenId, delegation.status);
558:         }
559: 
...
566: 
567:         // decrease the effective stake
568:         _updatePeriodEffectiveStake($, delegation.validator, _tokenId, completedPeriods + 2, false);
569: 
570:         emit DelegationExitRequested(_tokenId, delegation.validator, delegationId, exitBlock);
571:     }

The user’s stake stops being effective two periods after the current completed period. However, when claiming rewards, the protocol does not verify whether the delegation’s endPeriod has already passed. Because this check is missing, users are still allowed to claim rewards even after their delegation should no longer be eligible, leading to incorrect reward distribution.

In the above code snippet, we can see that there is no check to determine whether the endPeriod has already passed or whether the delegator has exited from the validator. As a result, an attacker or normal user can continue claiming rewards even though they no longer have an active delegation on this validator. The Docs clearly mention that :

Once exited, the NFT:

  1. Stops generating rewards

  2. Can be unstaked or delegated again

Impact Details

An attacker or user can continue claiming rewards even after their delegation is no longer active and has already exited, resulting in unauthorized reward extraction.

References

Section-Exitedarrow-up-right

Recommendation

One if the potential fix could be following :

Proof of Concept

Proof of Concept

Add the Following test case to the file test/unit/Stargate/Delegation.test.ts and run with command npx hardhat test

Was this helpful?