60372 sc high double decrement bug effective stake underflow permanently locks funds

Submitted on Nov 21st 2025 at 22:29:42 UTC by @arunabha003 for Audit Comp | Vechain | Stargate Hayabusaarrow-up-right

  • Report ID: #60372

  • 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

The Stargate contract contains a double-decrement accounting bug where _updatePeriodEffectiveStake() is called twice with the same effective stake value during the unstake flow when a validator has exited. First, requestDelegationExit() decrements the effective stake , then unstake() decrements it again when the validator status is EXITED. This causes an arithmetic underflow in _updatePeriodEffectiveStake() , permanently preventing users from unstaking and withdrawing their staked VET.

Vulnerability Details

The vulnerability exists in the effective stake accounting system across three functions in Stargate.sol:

Location 1: requestDelegationExit() - Line 565

function requestDelegationExit(uint256 _tokenId) external {
    // ... validation ...
    uint256 effectiveStake = _calculateEffectiveStake($, _tokenId);
    _updatePeriodEffectiveStake($, delegation.validator, effectiveStake, false);  // DECREMENT #1
    // ...
}

Location 2: unstake() - Lines 267-275

Location 3: _updatePeriodEffectiveStake() - Line 1007

Exploit Path:

  1. User stakes NFT and delegates to validator (validator status: ACTIVE)

  2. User calls requestDelegationExit(tokenId) while validator is ACTIVE

    • _updatePeriodEffectiveStake() decrements effective stake (DECREMENT #1)

    • delegatorsEffectiveStake[validator] reduced by user's effective stake

  3. Validator becomes EXITED (offline, slashed, or voluntary exit)

  4. User calls unstake(tokenId)

    • Condition at line 267 evaluates true: currentValidatorStatus == VALIDATOR_STATUS_EXITED

    • _updatePeriodEffectiveStake() attempts second decrement (DECREMENT #2)

    • currentValue - _effectiveStake underflows because value already decremented in step 2

    • Transaction reverts with arithmetic underflow

  5. User permanently unable to unstake or withdraw staked VET

The bug also triggers if delegation status becomes PENDING instead of validator becoming EXITED, following the same double-decrement logic.

Impact Details

Users who follow the sequence (stake → delegate → requestDelegationExit → validator exits → unstake) lose permanent access to their staked VET. The contract holds the VET but provides no recovery mechanism. There is no admin function to force-unstake on behalf of users, and no time-based unlock. The funds remain locked in the contract indefinitely.

Financial impact depends on the number of affected users and their stake amounts. VeChain Stargate NFT staking levels range from 600,000 VET (Level 1) to 25,000,000 VET (Level 7). If even a small percentage of high-level stakers encounter this bug during validator exits, the total locked value could reach tens of millions of VET.

This constitutes permanent freezing of funds per Immunefi's Critical impact definition: "user is no longer able to withdraw their funds" with no recovery path.

Proof of Concept

Test File: packages/contracts/test/integration/DoubleDecrementBugPOC.test.ts

Running the POC

Actual Output

File: packages/contracts/test/integration/DoubleDecrementBugPOC.test.ts

Was this helpful?