59809 sc high user balances are permanently frozen in specific delegation scenarios
Submitted on Nov 16th 2025 at 02:59:50 UTC by @hrmneffdii for Audit Comp | Vechain | Stargate Hayabusa
Report ID: #59809
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
This report details a critical vulnerability discovered in the Stargate contract's delegation logic. A flaw in the _delegate function can cause a validator's delegatorsEffectiveStake to be improperly reduced twice for the same user.
This "double-decrease" bug desynchronizes the validator's internal stake accounting, leading to an arithmetic underflow when another user attempts to interact with their own stake. As a result, other delegators on the same validator will have their funds permanently frozen, as all management functions (e.g., delegate, requestDelegationExit, unstake) will fail.
Vulnerability details
Path: _delegate() (during re-delegation)
Later, the validator exits. If the user then calls _delegate to move their stake to a new validator, the logic in _delegate can also reduce the original validator's EffectiveStake again:
_getDelegationStatusreturnsDelegationStatus.EXITEDfor the token.This triggers the conditional
if (status == DelegationStatus.EXITED || status == DelegationStatus.PENDING)which withdraws the user's VET viawithdrawDelegation.Later, a second condition
if (currentValidatorStatus == VALIDATOR_STATUS_EXITED || status == DelegationStatus.PENDING)is true and the code calls_updatePeriodEffectiveStake(..., isIncrease: false)a second time.
The code does not account for the stake already having been subtracted during requestDelegationExit, causing a double-decrease of the same user's stake from the validator's EffectiveStake.
Destructive scenario (PoC summary)
A validator has EffectiveStake = 3e18 (Alice 1.5e18 + Bob 1.5e18).
Bob calls requestDelegationExit. Validator EffectiveStake becomes 1.5e18 (3e18 - 1.5e18). (Correct)
Validator exits. Bob calls delegate to a new validator. Due to the bug, the code reduces the validator's EffectiveStake again, resulting in EffectiveStake = 0 (1.5e18 - 1.5e18). (Incorrect)
Alice (still delegated to the exited validator with 1.5e18) attempts to call delegate to move her funds.
The _delegate logic for Alice attempts _updatePeriodEffectiveStake(..., isIncrease: false):
currentValue = 0 (incorrect)
effectiveStake (Alice) = 1.5e18
updatedValue = currentValue - effectiveStake -> 0 - 1.5e18 This causes an arithmetic underflow (Solidity 0.8.x+), and Alice's transaction reverts.
The same underflow occurs for Alice if she calls requestDelegationExit or other management operations; her funds become effectively frozen with no in-contract fix available.
Impact: Critical — permanent and irrecoverable freeze of user funds. If one user on a validator executes the sequence (requestDelegationExit, then after validator exit re-delegate), remaining delegators on that validator can be permanently prevented from moving or exiting their stakes due to underflow reverts.
Proof of Concept
How to run
Run the following test: yarn contracts:test:unit:verbose -- -- --grep "User balances are permanently frozen in specific delegation scenarios"
Test Case (excerpt)
Was this helpful?