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

56872 sc critical freezing of funds

Submitted on Oct 21st 2025 at 12:37:02 UTC by @shadowHunter for Audit Comp | Belong

  • Report ID: #56872

  • Report Type: Smart Contract

  • Report severity: Critical

  • Target: https://github.com/belongnet/checkin-contracts/blob/main/contracts/v2/periphery/Staking.sol

  • Impacts:

    • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

    • Permanent freezing of funds

Description

Brief/Intro

The Staking contract mints shares to represent users’ staked positions. These shares are freely transferable ERC20 tokens because of ERC4626 inheritance.

The vault tracks staked positions in the stakes[address] array to enforce:

  • Minimum stake periods (minStakePeriod)

  • Reward distribution (proportional to shares)

  • Emergency withdrawal penalties

Transferring shares to another address does not update the internal stakes[] array, resulting in a permanent desync between the internal staking record and the transferable ERC20 shares.

1

Vulnerability Details — sequence of actions

  • Assume Alice and Bob are two users.

  • Alice deposits 100 LONG tokens → receives 100 sLONG shares.

  • Alice transfers 100 sLONG shares to Bob.

  • Bob now holds the shares but has no corresponding entries in stakes[Bob].

  • Bob attempts a normal withdraw → fails due to missing unlocked stake.

  • Bob can only use emergencyWithdraw → receives 90% of assets, losing 10% as a penalty.

2

Impact Details

  • The new holder of transferred shares cannot withdraw normally — the vault sees no unlocked shares.

  • Emergency withdrawal is the only recovery path, but it always imposes the configured penalty (10% by default).

  • Users effectively lose access to their funds or pay a financial cost simply due to a transfer.

This can lead to permanent freezing of funds.

Recommendation

Prevent permanent freezing by making shares non-transferable. For example:

Override ERC20 transfer and transferFrom to revert so shares cannot be moved without updating the internal bookkeeping.

Proof of Concept

Click to expand the full PoC test and observed output

Observed output: As expected Redeem reverts (vm.expectRevert())

Was this helpful?