Lucene search

K
code423n4Code4renaCODE423N4:2022-09-Y2K-FINANCE-FINDINGS-ISSUES-503
HistorySep 19, 2022 - 12:00 a.m.

rewarding is not started after StakingRewards contract deployment and there is no specific time set for contract start time of rewarding, users stacked their funds has no way knowing when is rewarding is going to be started

2022-09-1900:00:00
Code4rena
github.com
2

Lines of code
<https://github.com/code-423n4/2022-09-y2k-finance/blob/2175c044af98509261e4147edeb48e1036773771/src/rewards/StakingRewards.sol#L72-L87&gt;

Vulnerability details

Impact

after StakingRewards the constructor() logic set value for rewardRate and rewardsDuration but rewarding is not started for stackers and users has no way to find out when is rewarding going to be started. only reward Distributer can start rewarding process immediately by calling notifyRewards() and some functions like getRewardForDuration() return wrong values when rewarding is not started. this behavior can cause users to stake their funds without getting any rewards and knowing when they are gonna get rewards.

Proof of Concept

This is constructor() and notifyRewards() codes in StakingRewards contract:

function notifyRewardAmount(uint256 reward)
        external
        override
        onlyRewardsDistribution
        updateReward(address(0))
    {
        if (block.timestamp &gt;= periodFinish) {
            rewardRate = reward.div(rewardsDuration);
        } else {
            uint256 remaining = periodFinish.sub(block.timestamp);
            uint256 leftover = remaining.mul(rewardRate);
            rewardRate = reward.add(leftover).div(rewardsDuration);
        }

        // Ensure the provided reward amount is not more than the balance in the contract.
        // This keeps the reward rate in the right range, preventing overflows due to
        // very high values of rewardRate in the earned and rewardsPerToken functions;
        // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow.
        uint256 balance = rewardsToken.balanceOf(address(this));
        require(
            rewardRate &lt;= balance.div(rewardsDuration),
            "Provided reward too high"
        );

        lastUpdateTime = block.timestamp;
        periodFinish = block.timestamp.add(rewardsDuration);
        emit RewardAdded(reward);
    }

constructor(
        address _owner,
        address _rewardsDistribution,
        address _rewardsToken,
        address _stakingToken,
        uint256 _epochEnd,
        uint256 _rewardsDuration,
        uint256 _rewardRate
    ) Owned(_owner) {
        rewardsToken = ERC20(_rewardsToken);
        stakingToken = IERC1155(_stakingToken);
        rewardsDistribution = _rewardsDistribution;
        id = _epochEnd;
        rewardsDuration = _rewardsDuration;
        rewardRate = _rewardRate;
    }

As you can see constructor set value for rewardRate and rewardsDuration but the rewarding is not started after deployment and the rewardRate is some fake value which can cause users to get confused. rewarding only starts by calling notifyRewards() which sets value for lastUpdateTime and rewardsDuration that make rewards to be calculated and rewarding to be started.
so Users don’t know when rewarding is going to be started and if they don’t stake their funds they would lose some early time of staking when rewarding starts and if they stake early their funds would be idle for nothing.

Tools Used

VIM

Recommended Mitigation Steps

add some start time to contract or create time-lock mechanism for notifyRewards() functions.


The text was updated successfully, but these errors were encountered:

All reactions