Omniscia Steer Protocol Audit

DualStaking Code Style Findings

DualStaking Code Style Findings

DSG-01C: Inefficient Code Structure

Description:

The referenced if-else block within the StakingDualRewards::withdraw function will repeat the same statements across the code branches except for a single require check.

Example:

contracts/Staking/DualStaking.sol
812if (isLocked) {
813 require(block.timestamp > periodFinish, "Period is not finished");
814 _totalSupply = _totalSupply.sub(amount);
815 _balances[msg.sender] = _balances[msg.sender].sub(amount);
816 stakingToken.safeTransfer(msg.sender, amount);
817 emit Withdrawn(msg.sender, amount);
818} else {
819 _totalSupply = _totalSupply.sub(amount);
820 _balances[msg.sender] = _balances[msg.sender].sub(amount);
821 stakingToken.safeTransfer(msg.sender, amount);
822 emit Withdrawn(msg.sender, amount);
823}

Recommendation:

We advise the code to instead perform the require check within the existing if clause, the else clause to be removed, and the remaining statements in the if clause to be relocated outside of it and specifically after it.

Alleviation (6513a21a002d422e298719b22f73a4559dfd4663):

The code was optimized per our recommendation, significantly reducing the bytecode size of the contract.

DSG-02C: Inefficient Separation of Logic

Description:

The referenced if blocks will evaluate the same conditional.

Example:

contracts/Staking/DualStaking.sol
917if (account != address(0)) {
918 rewardsA[account] = earnedA(account);
919 userRewardPerTokenAPaid[account] = rewardPerTokenAStored;
920}
921
922if (account != address(0)) {
923 rewardsB[account] = earnedB(account);
924 userRewardPerTokenBPaid[account] = rewardPerTokenBStored;
925}

Recommendation:

We advise their statements to be merged into a single if block, optimizing the code's gas cost.

Alleviation (6513a21a002d422e298719b22f73a4559dfd4663):

The referenced if conditionals have been correctly placed under a single if conditional, optimizing their gas cost.

DSG-03C: Inefficient Variable Reads

Description:

The referenced statements will read the paused variable from storage inefficiently.

Example:

contracts/Staking/DualStaking.sol
642/**
643 * @notice Change the paused state of the contract
644 * @dev Only the contract owner may call this.
645 */
646function setPaused(bool _paused) external onlyOwner {
647 // Ensure we're actually changing the state before we do anything
648 if (_paused == paused) {
649 return;
650 }
651
652 // Set our paused state.
653 paused = _paused;
654
655 // If applicable, set the last pause time.
656 if (paused) {
657 lastPauseTime = now;
658 }
659
660 // Let everyone know that our pause state has changed.
661 emit PauseChanged(paused);
662}

Recommendation:

We advise them to be read from memory instead and specifically from the _paused member, optimizing the gas cost of the function.

Alleviation (6513a21a002d422e298719b22f73a4559dfd4663):

The inefficient storage reads have been replaced by reads of in-memory variables, optimizing the code's gas cost.

DSG-04C: Repetitive Value Literals

Description:

The linked value literals are repeated across the codebase multiple times.

Example:

contracts/Staking/DualStaking.sol
744return rewardRateA * 86400;

Recommendation:

We advise each to be set to its dedicated constant variable instead, optimizing the legibility of the codebase.

In case some of the constant declarations have already been introduced, we advise them to be properly re-used across the code.

Alleviation (6513a21a002d422e298719b22f73a4559dfd4663):

The referenced value literals SECONDS_IN_1_DAY, and PRECISION have all been relocated to contract-level constant declarations labelled 86400, and 1e18 respectively, optimizing the code's legibility.