56863 sc critical first depositor advantage

Submitted on Oct 21st 2025 at 10:37:35 UTC by @pawps for Audit Comp | Belongarrow-up-right

  • Report ID: #56863

  • 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

Description

Vulnerability Details

The Staking contract inherits from the ERC4626 standard. This contract is susceptible to a well-known exploit referred to as the "first depositor inflation attack." This vulnerability occurs due to the lack of protective mechanisms in the contract's design, allowing the initial depositor to manipulate the share price to their advantage.

This can enable the first depositor to disproportionately claim assets from the vault, effectively draining value at the expense of subsequent depositors.

An attacker/first depositor could simply:

  • Stake 1 receipt token into the contract, resulting in a 1:1 share price.

  • Donate 10,000 receipt tokens directly to the contract, causing the share price to become 10,001 units per share. OR admin calls distributeRewards with reward amount of receipt token (asset)

  • Subsequent deposits will receive no shares, and their deposit will be absorbed by the single share in the system that belongs to the first depositor.

In the Staking contract, no specific safeguards exist to prevent this attack. There is no minimum initial deposit requirement, nor is there any use of virtual shares to stabilize the share price, and there are no other mechanisms to ensure fairness.

circle-exclamation

Impact Details

This bug will brick the contract and cause loss total of funds

Proof of Concept

1

Setup / Step 0 — Fund attacker and victim

Fund victim with victimDepositAmount and attacker with attackerDonationAmount + 1 (1 for initial deposit, rest for donation). Verify initial vault state (totalSupply == 0, vault asset balance == 0).

2

Attacker deposits a tiny amount

Attacker approves and deposits 1 receipt token (or 1 wei). Vault mints 1 share to attacker; totalAssets == 1; totalSupply == 1.

3

Attacker inflates vault balance directly

Attacker transfers a large donation directly to the vault (e.g., 10,000 tokens). totalAssets becomes large while totalSupply remains 1, inflating the per-share asset value.

4

Victim deposits and receives 0 shares

Victim attempts to deposit victimDepositAmount. Because shares are calculated as floor(victimDepositAmount * totalSupply / totalAssets), this will round down to 0. The deposit increases the vault asset balance but grants 0 shares to the victim.

5

Attacker redeems the single share and withdraws all assets

After minStakePeriod, attacker redeems their single share and withdraws the entire vault balance (original donation + victim deposit), profiting at the expense of the victim.

Proof-of-Concept test (Solidity / Hardhat-style):

Was this helpful?