-
Notifications
You must be signed in to change notification settings - Fork 11
Description
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.