Omniscia Steer Protocol Audit

FeeManager Code Style Findings

FeeManager Code Style Findings

FMR-01C: Inefficient mapping Lookups

Description:

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

Example:

contracts/FeeManager.sol
184uint256 length = vaultFees[vault].length;
185for (uint256 i = 0; i < length; i++) {
186 for (uint256 j = 0; j < feeIdentifiers.length; j++) {
187 if (
188 keccak256(
189 abi.encodePacked(vaultFees[vault][i].feeIdentifier)
190 ) == keccak256(abi.encodePacked(feeIdentifiers[j]))
191 ) {
192 vaultFees[vault][i].feeValue = newFeeValues[j];
193 totalNewFeeValue += newFeeValues[j];
194 break;
195 }
196 }
197}

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.

As the compiler's optimizations may take care of these caching operations automatically at-times, we advise the optimization to be selectively applied, tested, and then fully adopted to ensure that the proposed caching model indeed leads to a reduction in gas costs.

Alleviation (6513a21a002d422e298719b22f73a4559dfd4663):

The relevant function the optimization was applicable to has been removed, rendering it inapplicable.

FMR-02C: Loop Iterator Optimizations

Description:

The linked for loops increment / decrement their iterator "safely" due to Solidity's built - in safe arithmetics (post-0.8.X).

Example:

contracts/FeeManager.sol
71for (uint256 i = 0; i < feeIdentifier.length; i++) {

Recommendation:

We advise the increment / decrement operations to be performed in an unchecked code block as the last statement within each for loop to optimize their execution cost.

Alleviation (6513a21a002d422e298719b22f73a4559dfd4663):

The referenced loop iterator increment statements have been relocated at the end of each respective for loop's body and have been unwrapped in an unchecked code block, optimizing their gas cost.

FMR-03C: Suboptimal Struct Declaration Styles

Description:

The linked declaration styles of the referenced structs are using index-based argument initialization.

Example:

contracts/FeeManager.sol
76vaultFees[vault].push(Fee(feeIdentifier[i], feeValue[i]));

Recommendation:

We advise the key-value declaration format to be utilized instead in each instance, greatly increasing the legibility of the codebase.

Alleviation (6513a21a00):

The Steer Protocol team specified that they need to use an array to represent this structure, however, we believe that the exhibit's purpose has been misinterpreted.

The exhibit states that the Fee structure (presently instantiated as Fee(feeIdentifier[i], feeValue[i])) should be instantiated using the key-value declaration syntax (i.e. Fee({feeIdentifier: feeIdentifier[i], feeValue: feeValue[i]})) which is a syntactical adjustment and has no bearing on the code's functionality.

Alleviation (dc34c6a066):

The key-value declaration style is properly in-use within the FeeManager for the Fee structure, addressing this exhibit in full.