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

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 Hayabusa

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