59850 sc high users funds stuck in the contract permanently

Submitted on Nov 16th 2025 at 11:59:09 UTC by @danvinci_20 for Audit Comp | Vechain | Stargate Hayabusaarrow-up-right

  • Report ID: #59850

  • 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

Summary

When a delegator requests a delegation exit, the contract immediately reduces their effective stake, but still allows the delegator to keep claiming rewards for future periods after exit. Because reward distribution uses effective stake ratios, the exited delegator’s artificially reduced effective stake distorts the share calculations for remaining delegators.

This leads to two severe effects:

  • Exited delegator steals rewards for periods they did not participate in.

  • Protocol VTHO balance becomes insufficient, causing remaining delegators to revert when calling unstake() due to: builtin: insufficient balance

→ Their VTHO rewards stolen + staked VET become permanently locked in the contract.

This is a funds-freezing critical vulnerability impacting all users still delegating.

Vulnerability Details

Root Cause requestDelegationExit() reduces the user’s effective stake immediately via:

But does not prevent the user from continuing to claim future rewards.

Reward Claim Logic Fails to Enforce End-of-Stake Boundary The function _claimableDelegationPeriods() returns periods even after stake exit:

Meaning: even after exit → if more periods pass → user keeps claiming.

Reward Settlement Logic Ignores End-Period The reward calculation:

does not check if the delegator was still staked for those periods. Exited delegator drains new rewards from future periods using a reduced effective stake, creating mathematically invalid reward shares.

Final Breakage Point

When a later delegator tries to call:

Because the contract no longer has enough VTHO to cover mandatory reward claims made inside unstake(), the call reverts:

  • The user is permanently stuck.

  • Funds are frozen.

  • Delegator 2 cannot exit.

Note

This bug is different from report 59665; even if that issue is fixed, this bug still occurs.

Proof of Concept

Run the test:

Test case demonstrating the issue:

Observed output:

Was this helpful?