code-423n4 / 2022-05-velodrome-findings

0 stars 0 forks source link

Gas Optimizations #165

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Gas

Optimize loop in Gauge#getReward

The rewards claiming loop in Gauge#getReward can be optimized with a few loop optimization tricks: caching loop length, using unchecked increments, and caching the intermediate token value. Since this will be a frequently called function, it's probably worth the extra optimization:

Gauge#getReward

        for (uint i = 0; i < tokens.length; i++) {
            (rewardPerTokenStored[tokens[i]], lastUpdateTime[tokens[i]]) = _updateRewardPerToken(tokens[i]);

            uint _reward = earned(tokens[i], account);
            lastEarn[tokens[i]][account] = block.timestamp;
            userRewardPerTokenStored[tokens[i]][account] = rewardPerTokenStored[tokens[i]];
            if (_reward > 0) _safeTransfer(tokens[i], account, _reward);

            emit ClaimRewards(msg.sender, tokens[i], _reward);
        }

Recommendation:

        uint256 length = tokens.length;
        for (uint i = 0; i < length;) {
            address token = tokens[i];
            (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token);

            uint _reward = earned(token, account);
            lastEarn[token][account] = block.timestamp;
            userRewardPerTokenStored[token][account] = rewardPerTokenStored[token];
            if (_reward > 0) _safeTransfer(token, account, _reward);

            emit ClaimRewards(msg.sender, token, _reward);
            unchecked { ++i; }
        }
GalloDaSballo commented 2 years ago

25 gas for the loop + 6 for the length