Omniscia Nexera Protocol Audit
DistributionManager Code Style Findings
DistributionManager Code Style Findings
DMR-01C: Inefficient Loop Limit Evaluations
Type | Severity | Location |
---|---|---|
Gas Optimization | DistributionManager.sol:L305, L331, L352, L377 |
Description:
The linked for
loops evaluate their limit inefficiently on each iteration.
Example:
305for (uint256 i = firstUnclaimedPayout; i < payments.length; i++) {
Recommendation:
We advise the statements within the for
loop limits to be relocated outside to a local variable declaration that is consequently utilized for the evaluations to significantly reduce the codebase's gas cost. We should note the same optimization is applicable for storage reads present in those limits as they are newly read on each iteration (i.e. length
members of arrays in storage).
Alleviation (fb50b5c39665f7df086b2de1fdbf93ba2d836bf9):
All referenced loop limit evaluations have been properly cached outside each for
loop's code block to a dedicated local variable that is consequently utilized in their place, optimizing each loop's gas cost significantly.
DMR-02C: Loop Iterator Optimizations
Type | Severity | Location |
---|---|---|
Gas Optimization | DistributionManager.sol:L120, L174, L305, L331, L352, L377, L410 |
Description:
The linked for
loops increment / decrement their iterator "safely" due to Solidity's built - in safe arithmetics (post-0.8.X
).
Example:
120for (uint256 i; i < tagsLength; 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 (fb50b5c396):
All for
loop iterator increments have been optimized, however, the for
loop within DistributionManager::_claimOwnerPayouts
contains a continue
statement that does not increment the iterator properly causing a loop that never terminates.
We advise the unchecked
increment statement to be relocated right after the collectToken
assignment, ensuring the loop continues as expected while being optimal.
Alleviation (938d6b02ca):
The iterator's increment statement was relocated right after the collectToken
assignment as advised, ensuring that the continue
statement does not affect the loop's ability to terminate and thus applying this exhibit's optimization safely.
DMR-03C: Redundant Function Argument
Type | Severity | Location |
---|---|---|
Gas Optimization | DistributionManager.sol:L369 |
Description:
The DistributionManager::_claimPayouts
function is solely invoked by the DistributionManager::claimDatasetOwnerAndFragmentPayouts
function which will in turn supply the ContextUpgradeable::_msgSender
as the function's argument at all times.
Example:
369function _claimPayouts(address beneficiary) internal {370 // Claim payouts371 uint256 firstUnclaimedPayout = _firstUnclaimedContribution[beneficiary];372 if (firstUnclaimedPayout >= payments.length) return; // Nothing to claim373 _firstUnclaimedContribution[beneficiary] = payments.length; // CEI pattern to prevent reentrancy374
375 address collectToken = payments[firstUnclaimedPayout].token;376 uint256 collectAmount;377 for (uint256 i = firstUnclaimedPayout; i < payments.length; i++) {378 Payment storage p = payments[i];379 if (collectToken != p.token) {380 // Payment token changed, send what we've already collected381 _sendPayout(collectToken, collectAmount, beneficiary);382 collectToken = p.token;383 collectAmount = 0;384 }385 collectAmount += _calculatePayout(p, beneficiary);386 }387 // send collected and not sent yet388 _sendPayout(collectToken, collectAmount, beneficiary);389}
Recommendation:
We advise the code to omit its input argument and to utilize the ContextUpgradeable::_msgSender
value directly, optimizing its gas cost.
This will also permit the function to be invoked by the DistributionManager::claimPayouts
function, reducing the overall bytecode size of the contract.
Alleviation (fb50b5c39665f7df086b2de1fdbf93ba2d836bf9):
The beneficiary
argument of the DistributionManager::_claimPayouts
function has been properly replaced by a local homonymous variable that is assigned with the value of ContextUpgradeable::_msgSender
as advised.
DMR-04C: Repetitive Value Literals
Type | Severity | Location |
---|---|---|
Code Style | DistributionManager.sol:L161, L201, L211 |
Description:
The linked value literals are repeated across the codebase multiple times.
Example:
161if (percentage > 5e17) revert PERCENTAGE_VALUE_INVALID(5e17, percentage);
Recommendation:
We advise each to be set to its dedicated constant
variable instead optimizing the legibility of the codebase.
Alleviation (fb50b5c39665f7df086b2de1fdbf93ba2d836bf9):
The referenced value literals 5e17
, and 1e18
have all been relocated to contract-level constant
declarations labelled MAX_DATASET_OWNER_PERCENTAGE
, and BASE_100_PERCENT
respectively, optimizing the code's legibility.