Omniscia Boson Protocol Audit

PausableBase Code Style Findings

PausableBase Code Style Findings

PBE-01C: Bytecode Size Optimization

TypeSeverityLocation
Gas OptimizationPausableBase.sol:L22, L34, L46, L58, L70, L82, L94, L106, L118, L130, L142, L154, L166

Description:

The linked require statements are replicated across multiple modifier implementations with the same error message.

Example:

contracts/protocol/bases/PausableBase.sol
14/**
15 * @dev Modifier that checks the Offers region is not paused
16 *
17 * Reverts if region is paused
18 *
19 * See: {BosonTypes.PausableRegion}
20 */
21modifier offersNotPaused() {
22 require(!paused(PausableRegion.Offers), REGION_PAUSED);
23 _;
24}
25
26/**
27 * @dev Modifier that checks the Twins region is not paused
28 *
29 * Reverts if region is paused
30 *
31 * See: {BosonTypes.PausableRegion}
32 */
33modifier twinsNotPaused() {
34 require(!paused(PausableRegion.Twins), REGION_PAUSED);
35 _;
36}

Recommendation:

We advise all require statements to instead invoke a private function that accepts a bool argument and reverts with the REGION_PAUSED error message thus significantly reducing the generated bytecode size of all contracts that use the modifiers.

Alleviation (44009967e4f68092941d841e9e0f5dd2bb31bf0b):

The paused function has instead been renamed to revertIfPaused and adequately optimizes each modifier's bytecode footprint as it now contains the error message and require call instead of yielding the pause status to its caller.

PBE-02C: Potential Operator Optimization

TypeSeverityLocation
Gas OptimizationPausableBase.sol:L177

Description:

The linked statement is meant to calculate the bit that should be validated as present in the pauseScenario variable, however, the bit is calculated using a power operation (**) which is expensive.

Example:

contracts/protocol/bases/PausableBase.sol
170/**
171 * @dev Check if a region of the protocol is paused.
172 *
173 * @param _region the region to check pause status for
174 */
175function paused(PausableRegion _region) internal view returns (bool) {
176 // Region enum value must be used as the exponent in a power of 2
177 uint256 powerOfTwo = 2**uint256(_region);
178 return (ProtocolLib.protocolStatus().pauseScenario & powerOfTwo) == powerOfTwo;
179}

Recommendation:

We advise a bitwise shift to be utilized instead, adjusting the assignment to 1 << uint256(_region) achieving the same result in cheaper operations.

Alleviation (44009967e4f68092941d841e9e0f5dd2bb31bf0b):

A bitwise shift operation is now correctly utilized to assess the power-of-two operation optimizing the codebase's gas cost.