Skip to content
This repository was archived by the owner on Sep 14, 2025. It is now read-only.
This repository was archived by the owner on Sep 14, 2025. It is now read-only.

Big Denim Viper - Reward Amount can be reduced if notifyRewardAmount is called in mid duration #686

@sherlock-admin3

Description

@sherlock-admin3

Big Denim Viper

High

Reward Amount can be reduced if notifyRewardAmount is called in mid duration

Summary

The duration reset in _addRewardsForToken will cause reduced rewards for stakers as any user can call notifyRewardAmount mid-period/duration to dilute rewards.

Root Cause

In SymmStaking.sol the _addRewardsForToken function resets the reward period duration to the default value (1 week) instead of using the remaining time from the current period when new rewards are added mid-period.
Anyone can call the notifyRewardAmount function anytime which will dilutes the rewards and the users will receives less reward because of the reward being diluted.

https://github.com/sherlock-audit/2025-03-symm-io-stacking/blob/main/token/contracts/staking/SymmStaking.sol#L270-L293

Internal Pre-conditions

  1. Admin needs to call configureRewardToken to whitelist a reward token (e.g., USDT).

  2. Any user needs to call notifyRewardAmount to initialize a reward period with a non-zero amount.

  3. At least sometime should be passed [eg : 3 days]

  4. Anyone can call the notifyRewardAmount function and add reward token in the protocol to decrease the rewardRate per token and it will result in users receiving less rewards.

External Pre-conditions

None

Attack Path

  1. Admin calls configureRewardToken to enable USDT as a reward token.
  2. Time passes lets assume 3 days after making few deposits by users.
  3. Someone will call notifyRewardAmount and add more USDT
  4. Contract will resets duration to 1 week again instead of using remaining 4 days
  5. Reward rate will drop resulting in user receiving less rewards

Impact

The stakers will suffer losses as per their expected rewards. Attackers can gried the system by intentionally diluting rewards

PoC

No response

Mitigation

  1. Modify _addRewardsForToken to use remaining time instead of resetting duration:
function _addRewardsForToken(address token, uint256 amount) internal {
		TokenRewardState storage state = rewardState[token];

		if (block.timestamp >= state.periodFinish) {
			state.rate = amount / state.duration;
		} else {
			uint256 remaining = state.periodFinish - block.timestamp;
			uint256 leftover = remaining * state.rate;
-			state.rate = (amount + leftover) / state.duration;
+                     state.rate = (amount + leftover) / remaining; 
+                     state.periodFinish = block.timestamp + remaining;
                		}

		state.lastUpdated = block.timestamp;
		state.periodFinish = block.timestamp + state.duration;
	}
  1. Restrict notifyRewardAmount: Add access control to prevent unauthorized users from diluting rewards:

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