Omniscia Evergon Labs Audit

ContinuousVirtualAmountMultiplierFacetStorage Code Style Findings

ContinuousVirtualAmountMultiplierFacetStorage Code Style Findings

CVF-01C: Inefficient Code Structure

Description:

The ContinuousVirtualAmountMultiplierFacetStorage::applyVirtualAmountMultiplier function is slightly inefficient as it will break a for loop and execute further statements when unnecessary as the multiplier is guaranteed to be non-zero in such a case.

Example:

packages/contracts/contracts/virtualAmountMultiplier/continuousVirtualAmountMultiplier/ContinuousVirtualAmountMultiplierFacetStorage.sol
166function applyVirtualAmountMultiplier(
167 Layout storage l,
168 uint256 campaignId,
169 uint256 nftId,
170 uint256 totalAmountStaked
171) internal returns (uint256) {
172 CampaignInfo storage campaignInfoLocal = l.campaignInfoLocal[campaignId];
173 uint256[] memory amountsStaked = campaignInfoLocal.amountsStaked;
174 uint256 virtualAmount = totalAmountStaked;
175
176 if (totalAmountStaked >= amountsStaked[0]) {
177 uint256 length = amountsStaked.length;
178 uint256[] memory amountStakedMultipliers = campaignInfoLocal.amountStakedMultipliers;
179
180 uint256 multiplier;
181
182 for (uint256 i = 1; i < length; i++) {
183 if (totalAmountStaked < amountsStaked[i]) {
184 uint256 stepper = ((totalAmountStaked - amountsStaked[i - 1]) *
185 (amountStakedMultipliers[i] - amountStakedMultipliers[i - 1])) /
186 (amountsStaked[i] - amountsStaked[i - 1]);
187 multiplier = amountStakedMultipliers[i - 1] + stepper;
188 virtualAmount = (virtualAmount * multiplier) / DIVIDER;
189
190 l.amountMultiplierForNftId[nftId] = multiplier;
191 break;
192 }
193 }
194
195 if (multiplier == 0) {
196 multiplier = amountStakedMultipliers[length - 1];
197 virtualAmount = (virtualAmount * multiplier) / DIVIDER;
198 l.amountMultiplierForNftId[nftId] = multiplier;
199 }
200 } else {
201 l.amountMultiplierForNftId[nftId] = DIVIDER;
202 }
203
204 return virtualAmount;
205}

Recommendation:

We advise the code to return the virtualAmount calculated instead of breaking and the highlighted if conditional to be omitted as it would no longer be necessary, optimizing the code's overall gas cost.

Alleviation (b64b659786cf3c84bea52feb3a69f546ba3601f0):

The code was updated per our recommendation, minimizing the required statements to yield a value and thus optimizing its gas cost.

CVF-02C: Non-Standard Storage Slot Definition

Description:

The referenced declaration will define a storage slot for use by a facet of the system's main EIP-2535 Diamond, however, the way it is declared does not adhere to the latest standards.

Example:

packages/contracts/contracts/virtualAmountMultiplier/continuousVirtualAmountMultiplier/ContinuousVirtualAmountMultiplierFacetStorage.sol
57/// @dev Unique identifier for the storage slot where the Layout struct is stored.
58bytes32 internal constant STORAGE_SLOT =
59 keccak256("evergonlabs.Staking.virtualAmountMultiplier.storage.ContinuousVirtualAmountMultiplierFacetStorage");

Recommendation:

We advise the EIP-7201 name-spaced layout approach to be adhered to similarly to OpenZeppelin and other relevant standard libraries, ensuring consistency among the ecosystem's widely utilized libraries and conforming to the latest standards.

Alleviation (b64b659786cf3c84bea52feb3a69f546ba3601f0):

The referenced slot definition has been updated to its standardized EIP-7201 representation, addressing this exhibit.

CVF-03C: Repetitive Value Literal

Description:

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

Example:

packages/contracts/contracts/virtualAmountMultiplier/continuousVirtualAmountMultiplier/ContinuousVirtualAmountMultiplierFacetStorage.sol
112if (GeneralStorage.layout().campaignsInfo[campaignId].state != 1) {

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

The referenced literal has been properly introduced as part of the GeneralStakingStorage declarations and specifically as an ON_CREATION state, addressing this exhibit.