69540 sc insight missing return value on withdraw and missing view function for withdrawable amount

Submitted on Mar 15th 2026 at 13:12:58 UTC by @hcrlen for Audit Comp | Folks Finance: Staking Contracts

  • Report ID: #69540

  • Report Type: Smart Contract

  • Report severity: Insight

  • Target: https://github.com/Folks-Finance/folks-staking-contracts/blob/main/src/Staking.sol

  • Impacts:

Description

Brief/Intro

The withdraw function returns nothing despite computing amountToClaim and rewardToClaim internally. Additionally there is no public view function to query the current withdrawable amount for a stake, forcing users and integrators to replicate the accrual math off-chain.

Vulnerability Details

Issue 1: withdraw returns nothing

function withdraw(uint8 stakeIndex) external nonReentrant {
    _withdraw(stakeIndex);
}

_withdraw computes:

But these values are never returned. The caller has no way to know how much they received without:

  • Parsing the Withdrawn event

  • Checking token balance before and after

Every other state-changing function returns useful data:

withdraw is the only user state-changing function that returns nothing.

Issue 2: No view function for withdrawable amount

_getAccrued is internal:

Users and integrators cannot query current withdrawable amount on-chain. They must:

  • Call getUserStake(user, stakeIndex) to get raw stake data

  • Manually compute _getAccrued off-chain

  • Subtract claimedAmount and claimedReward

This makes it harder for frontends to display accurate withdrawable amounts and for other contracts to integrate with the staking contract.

Impact Details

Users and integrators cannot determine withdrawable amounts on-chain, and callers of withdraw receive no feedback on how much was claimed.

References

Add any relevant links to documentation or code

Proof of Concept

1

Observe every other user-facing state-changing function returns useful data

2

withdraw returns nothing despite computing meaningful values

3

_withdraw computes amountToClaim and rewardToClaim internally but discards them

4

A contract integrating with withdraw cannot know how much was claimed

5

User must rely on Withdrawn event

6

_getAccrued is internal not callable externally

7

getUserStake(user, stakeIndex) returns only raw stake data with no computed withdrawable amount

8

To compute withdrawable amount, user must manually replicate off-chain

9

No public on-chain function exists to compute this users, frontends, and integrating contracts must replicate _getAccrued logic off-chain

  • Off-chain rounding differences vs on-chain result

  • Incorrect withdrawable amount displayed to users

  • Integrating contracts unable to query withdrawable amount before calling withdraw

Was this helpful?