60373 sc high incorrect effective stake decrement when validator exits causes permanent freezing of user stake

Submitted on Nov 21st 2025 at 22:40:57 UTC by @x0xmechanic for Audit Comp | Vechain | Stargate Hayabusaarrow-up-right

  • Report ID: #60373

  • 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:

    • Permanent freezing of funds

Description

Brief/Intro

When a validator exits after the delegator has already requested delegation exit, the protocol incorrectly decrements the validator’s effective stake a second time when the user later calls unstake or redelegates the NFT. This double decrement causes an arithmetic underflow in _updatePeriodEffectiveStake, making both unstake and delegate revert permanently for that token. As a result, the delegator cannot recover their staked VET, leading to permanent freezing of funds (Critical).

Vulnerability Details

The core issue is how Stargate updates a validator’s effective stake when:

  • A delegation has already EXITED,

  • The validator itself has also EXITED, and

  • The user later calls unstake or delegate again.

Once a delegator has exited, the protocol has already decreased the validator’s effective stake for that token via _updatePeriodEffectiveStake as part of the normal exit flow when the user calls requestDelegationExit. After this point, delegatorsEffectiveStake[validator].upperLookup(period) correctly reflects the reduced value (often going to zero if this was the only delegator).

Later, when the user calls unstake after both:

  • the delegation is EXITED, and

  • the validator is in status EXITED,

we hit the branch:

Concretely, that branch does roughly this:

_updatePeriodEffectiveStake is called again with false (subtract), over periods where the first decrement has already been applied. This leads to:

  • An underflow (panic 0x11) , or

  • Double subtraction of their amount from the validator’s effective stake if other delegators remain.

The same double-decrement pattern appears when re-delegating, since delegate also calls _updatePeriodEffectiveStake under currentValidatorStatus == VALIDATOR_STATUS_EXITED. In both cases, once the validator and delegation have exited, subsequent unstake and re-delegate calls revert due to underflow in _updatePeriodEffectiveStake, preventing users from recovering or moving their staked funds.

Impact Details

  • Critical – Permanent freezing of funds

In the single delegator case, once:

  • The delegation is EXITED, and

  • The validator is EXITED

both:

  • unstake(tokenId) and

  • delegate(tokenId, newValidator)

permanently revert with panic 0x11 in _updatePeriodEffectiveStake. There is no alternative user accessible function that allows withdrawal of the staked VET. Their VET is permanently frozen.

In the multi-delegator case:

  • The double decrement leads to incorrect delegatorsEffectiveStake[validator], reducing it to zero while some delegations still exist.

  • This can:

    • Underpay remaining delegators (they receive rewards as if there were no stake), and/or

    • Break any logic relying on effective stake (reward share, monitoring, etc.).

Even in the multi-delegator case, if the remaining delegators’ combined effective stake is smaller than the exiting delegator’s stake (because of different token levels), the second decrease in _updatePeriodEffectiveStake will underflow and cause their subsequent unstake or delegate calls to revert (freezing of funds).

Proof of Concept

Proof of Concept

We show the bug with two tests:

  • Test "should revert when unstaking after validator exit due to effective stake underflow"

  1. A user stakes and delegates the stake to a validator: Effective stake of the validator increases.

  2. The user then calls requestDelegationExit: Effective stake of the validator becomes zero.

  3. The validator exits.

  4. The user calls unstake: The call reverts because of underflow in _updatePeriodEffectiveStake

Same with delegate: The user calls delegate: The call reverts because of underflow in _updatePeriodEffectiveStake

  • Test "should reduce effective stake twice incorrectly"

  1. Two users stake and delegate the stake to a validator: Effective stake of the validator increases by the sum of the two stakes.

  2. One user then calls requestDelegationExit: Effective stake of the validator decreases by half.

  3. The validator exits.

  4. The user who exited calls delegate: The effective stake of the validator becomes zero (the user's stake was incorrectly subtracted again).

Here are the tests:

We used TEST_LOGS=1 VITE_APP_ENV=local npx hardhat test --network hardhat test/unit/Stargate/ReportUnstake.test.ts

Was this helpful?