Omniscia Alliance Block Audit
RewardsPoolFactory Code Style Findings
RewardsPoolFactory Code Style Findings
RPF-01C: Data Location Optimization
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | Informational | RewardsPoolFactory.sol:L35, L36, L103 |
Description:
The deploy function contains two dynamic array arguments that are stored in memory and is declared as external. The extendRewardPool function contains a single dynamic array argument stored in memory and is declared external as well
Example:
31function deploy(32 address _stakingToken,33 uint256 _startBlock,34 uint256 _endBlock,35 address[] memory _rewardsTokens,36 uint256[] memory _rewardPerBlock,37 uint256 _stakeLimit38) external onlyOwner {Recommendation:
We advise that the data location the arrays are stored in is changed to calldata to optimize the gas cost of the code segments.
Alleviation:
The variables involved in the deploy function were indeed optimized, however, the latter of the three remains unoptimized and we advise it to be done so.
RPF-02C: Redundant Usage of SafeMath
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | Informational | RewardsPoolFactory.sol:L118 |
Description:
The linked safeTransfer invocation passes in the result of a SafeMath subtraction between the variables newRemainingReward and currentRemainingReward whereas the whole statement is included within an if clause that ensures newRemainingReward is strictly greater-than currentRemainingReward.
Example:
110for (uint256 i = 0; i < _rewardsPerBlock.length; i++) {111 uint256 currentRemainingReward = calculateRewardsAmount(block.number, currentEndBlock, pool.rewardPerBlock(i));112 uint256 newRemainingReward = calculateRewardsAmount(block.number, _endBlock, _rewardsPerBlock[i]);113114 address rewardsToken = RewardsPoolBase(_rewardsPoolAddress).rewardsTokens(i);115116 if (newRemainingReward > currentRemainingReward) {117 // Some more reward needs to be transferred to the rewards pool contract118 IERC20Detailed(rewardsToken).safeTransfer(_rewardsPoolAddress, newRemainingReward.sub(currentRemainingReward));119 }120}Recommendation:
We advise that the sub invocation is safely omitted as the subtraction is guaranteed to never underflow, optimizing the gas cost of the function.
Alleviation:
The redundant SafeMath utilization was replaced by its raw counterpart optimizing the gas cost of the function.
RPF-03C: Redundant Validation Loop
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | Informational | RewardsPoolFactory.sol:L52-L61 |
Description:
Within Solidity gas costs are of great concern and as such code should be developed as optimal as possible. The linked for loop validates the input _rewardsTokens and _rewardPerBlock prior to their utilization in the ensuing for loop of L79-L90 redundantly so.
Example:
52for (uint256 i = 0; i < _rewardsTokens.length; i++) {53 require(54 _rewardsTokens[i] != address(0),55 "RewardsPoolFactory::deploy: Reward token address could not be invalid"56 );57 require(58 _rewardPerBlock[i] != 0,59 "RewardsPoolFactory::deploy: Reward per block must be greater than zero"60 );61}62 require(63 _stakeLimit != 0,64 "RewardsPoolFactory::deploy: Stake limit must be more than 0"65);6667address rewardsPoolBase =68 address(69 new RewardsPoolBase(70 IERC20Detailed(_stakingToken),71 _startBlock,72 _endBlock,73 _rewardsTokens,74 _rewardPerBlock,75 _stakeLimit76 )77 );7879for (uint256 i = 0; i < _rewardsTokens.length; i++) {80 uint256 rewardsAmount =81 calculateRewardsAmount(82 _startBlock,83 _endBlock,84 _rewardPerBlock[i]85 );86 IERC20Detailed(_rewardsTokens[i]).safeTransfer(87 rewardsPoolBase,88 rewardsAmount89 );90}Recommendation:
We advise that the validation is performed directly on the for loop that utilizes the variables so as to reduce the gas cost involved in utilizing the function.
Alleviation:
The redundant for sanitization loop was omitted and its inner statements were placed under the for loop they are directly utilized in.