code-423n4 / 2021-11-streaming-findings

0 stars 0 forks source link

`Stream#claimReward()` storage writes and reads of `ts.rewards` can be combined into one #259

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

In Stream#claimReward(), ts.rewards is written 2 times and read once. Combing them into one storage write can save gas.

https://github.com/code-423n4/2021-11-streaming/blob/56d81204a00fc949d29ddd277169690318b36821/Streaming/src/Locke.sol#L555-L578

    function claimReward() public lock {
        require(block.timestamp > endRewardLock, "lock");

        TokenStream storage ts = tokensNotYetStreamed[msg.sender];
        // accumulate reward per token info
        cumulativeRewardPerToken = rewardPerToken();

        // update user rewards
        ts.rewards = earned(ts, cumulativeRewardPerToken);
        // update users last cumulative reward per token
        ts.lastCumulativeRewardPerToken = cumulativeRewardPerToken;

        lastUpdate = lastApplicableTime();

        uint256 rewardAmt = ts.rewards;
        ts.rewards = 0;

        require(rewardAmt > 0, "amt");

        // transfer the tokens
        ERC20(rewardToken).safeTransfer(msg.sender, rewardAmt);

        emit RewardsClaimed(msg.sender, rewardAmt);
    }

Recommendation

Change to:

    function claimReward() public lock {
        require(block.timestamp > endRewardLock, "lock");

        TokenStream storage ts = tokensNotYetStreamed[msg.sender];
        // accumulate reward per token info
        cumulativeRewardPerToken = rewardPerToken();

        uint256 rewardAmt = earned(ts, cumulativeRewardPerToken);
        require(rewardAmt > 0, "amt");
        // update users last cumulative reward per token
        ts.lastCumulativeRewardPerToken = cumulativeRewardPerToken;

        lastUpdate = lastApplicableTime();

        ts.rewards = 0;

        // transfer the tokens
        ERC20(rewardToken).safeTransfer(msg.sender, rewardAmt);

        emit RewardsClaimed(msg.sender, rewardAmt);
    }