Omniscia Steer Protocol Audit

StakingRewards Code Style Findings

StakingRewards Code Style Findings

SRS-01C: Generic Typographic Mistakes

TypeSeverityLocation
Code StyleStakingRewards.sol:L30, L42, L78, L187

Description:

The referenced lines contain typographical mistakes or generic documentational errors (i.e. copy-paste) that should be corrected.

Example:

contracts/StakingRewards.sol
30mapping(uint256 => pool) public Pools;

Recommendation:

We advise them to be corrected enhancing the legibility of the codebase.

Alleviation (200f275c40):

All mistakes were corrected apart for toggleStakingInPool which represents a setter function, not a toggle function.

Alleviation (0ed41ccc18):

The toggleStakignInPool function was aptly renamed to setJobState thus rendering this exhibit alleviated in full.

SRS-02C: Inefficient Mapping System

TypeSeverityLocation
Gas OptimizationStakingRewards.sol:L36, L39, L42, L51

Description:

The mapping declarations of the contract follow a many-to-one approach for the pools which is inefficient.

Example:

contracts/StakingRewards.sol
206function updateReward(uint256 _poolId, pool memory _pool) internal {
207 uint256 stakeTime;
208 if (block.timestamp > _pool.end) stakeTime = _pool.end;
209 else stakeTime = block.timestamp;
210 uint256 lastReward = (_balances[msg.sender][_poolId] *
211 (((stakeTime - lastRewarded[msg.sender][_poolId]) *
212 (_pool.rewardRate * PRECISION)) /
213 (RATE_PRECISION * SECONDS_IN_YEAR))) / PRECISION;
214 lastRewarded[msg.sender][_poolId] = stakeTime;
215 rewards[msg.sender][_poolId] += lastReward;
216}

Recommendation:

We advise a one-to-many approach to be utilized instead, storing data per pool per user rather than per user per pool which will allow lookups to be cached and generally lead to a significant reduction in the operational gas cost of the contract.

Alleviation (200f275c40cbd4798f4a416c044ea726755d4741):

The mapping system was revised to use our recommended entity relation scheme, storing data per pool ID per user in a single struct rather than retaining multiple independent mapping entries.

SRS-03C: Inefficient mapping Lookups

TypeSeverityLocation
Gas OptimizationStakingRewards.sol:L197, L198

Description:

The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.

Example:

contracts/StakingRewards.sol
196function claimPendingRewards(uint256 _poolId) external {
197 uint256 pending = pendingRewards[msg.sender][_poolId];
198 pendingRewards[msg.sender][_poolId] = 0;
199 totalRewardsPerPool[_poolId] -= pending;
200 IERC20Upgradeable(Pools[_poolId].rewardToken).safeTransfer(
201 msg.sender,
202 pending
203 );
204}

Recommendation:

As the lookups internally perform an expensive keccak256 operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping in case of primitive types or holds a storage pointer to the struct contained.

Alleviation (0ed41ccc18a72b7e559b8d79ab7ba6172362ee3b):

The Steer Protocol stated that this optimization lead to an increase in gas cost instead of a reduction. We would like to request an atomic gas comparison of the statements to showcase this as the gas cost associated with the optimization cannot increase due to how the EVM operates.