Omniscia Alliance Block Audit
LiquidityMiningCampaignFactory Code Style Findings
LiquidityMiningCampaignFactory Code Style Findings
LMF-01C: Data Location Optimization
Type | Severity | Location |
---|---|---|
Gas Optimization | Informational | LiquidityMiningCampaignFactory.sol:L38, L39, L106 |
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:
34function deploy(35 address _stakingToken,36 uint256 _startBlock,37 uint256 _endBlock,38 address[] memory _rewardsTokens,39 uint256[] memory _rewardPerBlock,40 uint256 _stakeLimit41) 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 data location specifiers of the linked external
function arguments was properly adjusted to calldata
.
LMF-02C: Redundant Usage of SafeMath
Type | Severity | Location |
---|---|---|
Gas Optimization | Informational | LiquidityMiningCampaignFactory.sol:L121 |
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:
113for (uint256 i = 0; i < _rewardsPerBlock.length; i++) {114 uint256 currentRemainingReward = calculateRewardsAmount(block.number, currentEndBlock, pool.rewardPerBlock(i));115 uint256 newRemainingReward = calculateRewardsAmount(block.number, _endBlock, _rewardsPerBlock[i]);116117 address rewardsToken = RewardsPoolBase(_rewardsPoolAddress).rewardsTokens(i);118119 if (newRemainingReward > currentRemainingReward) {120 // Some more reward needs to be transferred to the rewards pool contract121 IERC20Detailed(rewardsToken).safeTransfer(_rewardsPoolAddress, newRemainingReward.sub(currentRemainingReward));122 }123}
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 sub
invocation was properly replaced by a raw subtraction.
LMF-03C: Redundant Validation Loop
Type | Severity | Location |
---|---|---|
Gas Optimization | Informational | LiquidityMiningCampaignFactory.sol:L55-L64 |
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 L82-L93 redundantly so.
Example:
55for (uint256 i = 0; i < _rewardsTokens.length; i++) {56 require(57 _rewardsTokens[i] != address(0),58 "LiquidityMiningCampaignFactory::deploy: Reward token address could not be invalid"59 );60 require(61 _rewardPerBlock[i] != 0,62 "LiquidityMiningCampaignFactory::deploy: Reward per block must be greater than zero"63 );64}65 require(66 _stakeLimit != 0,67 "LiquidityMiningCampaignFactory::deploy: Stake limit must be more than 0"68);6970address rewardsPoolBase =71 address(72 new LiquidityMiningCampaign(73 IERC20Detailed(_stakingToken),74 _startBlock,75 _endBlock,76 _rewardsTokens,77 _rewardPerBlock,78 _stakeLimit79 )80 );8182for (uint256 i = 0; i < _rewardsTokens.length; i++) {83 uint256 rewardsAmount =84 calculateRewardsAmount(85 _startBlock,86 _endBlock,87 _rewardPerBlock[i]88 );89 IERC20Detailed(_rewardsTokens[i]).safeTransfer(90 rewardsPoolBase,91 rewardsAmount92 );93}
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 validation loop was properly removed from the codebase.