Skip to content

Stake Manipulation via Arbitrary Height Setting #284

@LevilkTheReal

Description

@LevilkTheReal

A user can manipulate their committedStake to near-zero by supplying a very high _height value while staking a minimal amount. This allows them to immediately withdraw almost all their funds by creating a situation where:

surplusStake = potentialStake - effectiveStake

becomes equal to potentialStake, because effectiveStake ≈ 0

The bug stems from this logic in the stake extension function:

if (_addAmount > 0) {
    updatedPotentialStake = stakes[msg.sender].potentialStake + _addAmount;
    updatedCommittedStake = updatedPotentialStake / (OracleContract.currentPrice() * 2 ** _height);
}

And how effectiveStake is calculated later:

function calculateEffectiveStake(
    uint256 committedStake,
    uint256 potentialStakeBalance,
    uint8 height
) internal view returns (uint256) {
    uint256 committedStakeBzz = (2 ** height) * committedStake * OracleContract.currentPrice();

    if (committedStakeBzz < potentialStakeBalance) {
        return committedStakeBzz;
    } else {
        return potentialStakeBalance;
    }
}

Steps to Reproduce
Stake a very small amount of PLUR (e.g., 1 unit) and set _height to a large value (e.g., 102).

As a result:
committedStake becomes close to zero, effectiveStake is extremely low.
Call withdraw. Nearly all of potentialStake is seen as surplusStake and becomes withdrawable.

Impact
Users can bypass commitment logic by artificially deflating their committedStake.
Undermines the security guarantees of the staking mechanism.
Could be used for griefing or staking without real commitment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions