Omniscia Sova Network Audit

tRWA Code Style Findings

tRWA Code Style Findings

RWA-01C: Inefficient Hook Activity Tracking

TypeSeverityLocation
Gas OptimizationtRWA.sol:
I-1: L182
I-2: L226
I-3: L377

Description:

The tRWA system will track whether a particular hook has been processed operations by setting the hasProcessedOperations value of it to true whenever it is invoked; a practice that is significantly inefficient as it results in an unnecessary storage write.

Example:

src/token/tRWA.sol
176for (uint256 i = 0; i < opHooks.length;) {
177 IHook.HookOutput memory hookOutput = opHooks[i].hook.onBeforeDeposit(address(this), by, assets, to);
178 if (!hookOutput.approved) {
179 revert HookCheckFailed(hookOutput.reason);
180 }
181 // Mark hook as having processed operations
182 opHooks[i].hasProcessedOperations = true;
183
184 unchecked {
185 ++i;
186 }
187}

Recommendation:

We advise the code to be revised, using a block number based approach. Effectively, the tRWA contract can mark the block number at which each operation hook type has been invoked.

This permits the existing addedAtBlock value to be utilized for comparisons, preventing the removal of a hook if the block number at which the operationType hooks were executed is greater than the block number at which the hook was introduced.

Alleviation (e4d6885477438291b0d3ca477fab7e088522967b):

The code was refactored as advised, tracking the block number at which each hook type has been executed and comparing it to the block number the hook itself was introduced at when assessing whether it can be removed.

RWA-02C: Inefficient mapping Lookups

TypeSeverityLocation
Gas OptimizationtRWA.sol:
I-1: L177, L182
I-2: L221, L226
I-3: L255, L256
I-4: L269, L271
I-5: L372, L377

Description:

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

Example:

src/token/tRWA.sol
177IHook.HookOutput memory hookOutput = opHooks[i].hook.onBeforeDeposit(address(this), by, assets, to);
178if (!hookOutput.approved) {
179 revert HookCheckFailed(hookOutput.reason);
180}
181// Mark hook as having processed operations
182opHooks[i].hasProcessedOperations = true;

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 (e4d6885477):

The optimization recommended has been partially applied as instance I-4 remains suboptimal.

Alleviation (08da17ef72):

The last remaining instance has been optimized as advised, alleviating this exhibit.

RWA-03C: Non-Standard Library Usage

TypeSeverityLocation
Code StyletRWA.sol:
I-1: L234
I-2: L395

Description:

In contrast to the rest of the codebase, the tRWA contract will invoke the relevant SafeTransferLib functions directly from the library rather than using them through the address data type.

Example:

src/token/tRWA.sol
395SafeTransferLib.safeTransferFrom(asset(), strategy, address(this), assets);

Recommendation:

We advise the library to be used via the functions exposed from the native address, optimizing the code's legibility.

Alleviation (e4d6885477438291b0d3ca477fab7e088522967b):

All instances of SafeTransferLib library usage have been replaced with proper syntax as exposed by the address type directly, addressing this exhibit.

RWA-04C: Potentially Redundant Shift Operation

TypeSeverityLocation
Gas OptimizationtRWA.sol:L274

Description:

The referenced assignment is redundantly performed when the index being removed matches the last index of the array.

Example:

src/token/tRWA.sol
265function removeOperationHook(bytes32 operationType, uint256 index) external onlyStrategy nonReentrant {
266 HookInfo[] storage opHooks = operationHooks[operationType];
267
268 if (index >= opHooks.length) revert HookIndexOutOfBounds();
269 if (opHooks[index].hasProcessedOperations) revert HookHasProcessedOperations();
270
271 address removedHookAddress = address(opHooks[index].hook);
272
273 // Remove by swapping with last element and popping (more gas efficient)
274 opHooks[index] = opHooks[opHooks.length - 1];
275 opHooks.pop();
276
277 emit HookRemoved(operationType, removedHookAddress);
278}

Recommendation:

We advise the code to perform the assignment solely when index is not equal to the opHooks.length - 1 value, optimizing the code's gas cost.

Alleviation (e4d6885477438291b0d3ca477fab7e088522967b):

The referenced array shift's execution has been optimized by wrapping it in the conditional recommended.

RWA-05C: Repetitive Value Literal

TypeSeverityLocation
Code StyletRWA.sol:L97, L150

Description:

The linked value literal is repeated across the codebase multiple times.

Example:

src/token/tRWA.sol
97if (assetDecimals_ > 18) revert InvalidDecimals();

Recommendation:

We advise it to be set to a constant variable instead, optimizing the legibility of the codebase.

In case the constant has already been declared, we advise it to be properly re-used across the code.

Alleviation (e4d6885477438291b0d3ca477fab7e088522967b):

The referenced 18 value literal has been properly replaced with the existing _DEFAULT_UNDERLYING_DECIMALS constant, addressing this exhibit.