Omniscia Sova Network Audit
tRWA Code Style Findings
tRWA Code Style Findings
RWA-01C: Inefficient Hook Activity Tracking
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | tRWA.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:
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 operations182 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
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | tRWA.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:
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 operations182opHooks[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
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | tRWA.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:
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
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | tRWA.sol:L274 |
Description:
The referenced assignment is redundantly performed when the index being removed matches the last index of the array.
Example:
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
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | tRWA.sol:L97, L150 |
Description:
The linked value literal is repeated across the codebase multiple times.
Example:
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.
