Omniscia Evergon Labs Audit
FixedInterestBuybackAmountFacetStorage Code Style Findings
FixedInterestBuybackAmountFacetStorage Code Style Findings
FIA-01C: Inefficient Data Management
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | FixedInterestBuybackAmountFacetStorage.sol:L93-L95, L104-L106 |
Description:
The FixedInterestBuybackAmountFacetStorage::_getObligationAndBuybackAmount function will copy the FungibleAndSemiFungiblePurchaseStorage.IdInfo structure to memory twice; once in the function locally and once more in the FixedInterestBuybackAmountFacetStorage::_calculateBuyBackAmount function invoked.
Example:
92function _calculateBuyBackAmount(Layout storage l, uint256 campaignId) internal view returns (uint256) {93 FungibleAndSemiFungiblePurchaseStorage.IdInfo memory infoForId = FungibleAndSemiFungiblePurchaseStorage.layout().infoForId[94 campaignId95 ];96
97 uint256 fundedAmount = infoForId.totalFractionsPurchased * infoForId.pricePerFraction;98 uint256 requiredBuybackAmount = fundedAmount + ((fundedAmount * l.interestPercentageForId[campaignId]) / _ONE_MILLION);99
100 return requiredBuybackAmount;101}102
103function _getObligationAndBuybackAmount(Layout storage l, uint256 campaignId) internal view returns (uint256, uint256) {104 FungibleAndSemiFungiblePurchaseStorage.IdInfo memory infoForId = FungibleAndSemiFungiblePurchaseStorage.layout().infoForId[105 campaignId106 ];107 uint256 requiredBuybackAmount = _calculateBuyBackAmount(l, campaignId);108
109 return (requiredBuybackAmount, requiredBuybackAmount / infoForId.totalFractionsPurchased);110}Recommendation:
We advise the FixedInterestBuybackAmountFacetStorage::_calculateBuyBackAmount function to be updated to accept the memory structure directly, optimizing the function's gas cost significantly.
Alleviation (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):
Information is now optimally exchanged between the FixedInterestBuybackAmountFacetStorage::getBuybackAmount and FixedInterestBuybackAmountFacetStorage::_getObligationPerFraction functions, addressing this exhibit.
FIA-02C: Misleading Function Name
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | FixedInterestBuybackAmountFacetStorage.sol:L103, L109 |
Description:
The FixedInterestBuybackAmountFacetStorage::_getObligationAndBuybackAmount function will yield the buyback amount and the obligation per fraction thereby contradicting the function name's order.
Example:
103function _getObligationAndBuybackAmount(Layout storage l, uint256 campaignId) internal view returns (uint256, uint256) {104 FungibleAndSemiFungiblePurchaseStorage.IdInfo memory infoForId = FungibleAndSemiFungiblePurchaseStorage.layout().infoForId[105 campaignId106 ];107 uint256 requiredBuybackAmount = _calculateBuyBackAmount(l, campaignId);108
109 return (requiredBuybackAmount, requiredBuybackAmount / infoForId.totalFractionsPurchased);110}Recommendation:
We advise the function name's order and the actual arguments yielded to follow the same order, ensuring consistency is maintained within the codebase.
Alleviation (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):
The function no longer yields two values simultaneously as part of FIA-04C and was renamed thus indirectly addressing this exhibit.
FIA-03C: Non-Standard Storage Slot Definition
| Type | Severity | Location |
|---|---|---|
| Standard Conformity | ![]() | FixedInterestBuybackAmountFacetStorage.sol:L30 |
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:
30bytes32 internal constant STORAGE_SLOT = keccak256("Evergonlabs.Tmi-Tokenizer.storage.FixedInterestBuybackAmountFacetStorage");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 (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):
The referenced slot definition has been updated to its standardized EIP-7201 representation, addressing this exhibit.
FIA-04C: Redundant Yielding of Buyback Amount
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | FixedInterestBuybackAmountFacetStorage.sol:L103-L110 |
Description:
The FixedInterestBuybackAmountFacetStorage::_getObligationAndBuybackAmount function is solely utilized within the contract itself and its first return argument is always ignored.
Example:
78function handleBuybackAmounts(Layout storage l, uint256 campaignId, uint256 buybackAmount) internal {79 (, uint256 obligationToEachFraction) = _getObligationAndBuybackAmount(l, campaignId);80
81 BuybackStorage.layout().obligationToEachFractionPerId[campaignId] = obligationToEachFraction;82
83 uint256 requiredBuybackAmount = ILendingOracleFacet(address(this)).getRemainingObligation(campaignId);84
85 if (requiredBuybackAmount != buybackAmount) revert WrongBuybackAmount(requiredBuybackAmount, buybackAmount);86}87
88function getBuybackAmount(Layout storage l, uint256 campaignId) internal view returns (uint256 requiredBuybackAmount) {89 requiredBuybackAmount = _calculateBuyBackAmount(l, campaignId);90}91
92function _calculateBuyBackAmount(Layout storage l, uint256 campaignId) internal view returns (uint256) {93 FungibleAndSemiFungiblePurchaseStorage.IdInfo memory infoForId = FungibleAndSemiFungiblePurchaseStorage.layout().infoForId[94 campaignId95 ];96
97 uint256 fundedAmount = infoForId.totalFractionsPurchased * infoForId.pricePerFraction;98 uint256 requiredBuybackAmount = fundedAmount + ((fundedAmount * l.interestPercentageForId[campaignId]) / _ONE_MILLION);99
100 return requiredBuybackAmount;101}102
103function _getObligationAndBuybackAmount(Layout storage l, uint256 campaignId) internal view returns (uint256, uint256) {104 FungibleAndSemiFungiblePurchaseStorage.IdInfo memory infoForId = FungibleAndSemiFungiblePurchaseStorage.layout().infoForId[105 campaignId106 ];107 uint256 requiredBuybackAmount = _calculateBuyBackAmount(l, campaignId);108
109 return (requiredBuybackAmount, requiredBuybackAmount / infoForId.totalFractionsPurchased);110}Recommendation:
We advise the function to solely yield the obligation per fraction, optimizing its gas cost.
Alleviation (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):
The function was updated to solely yield the obligation per fraction, optimizing the code's gas cost as advised.
FIA-05C: Repetitive Value Literal
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | FixedInterestBuybackAmountFacetStorage.sol:L33 |
Description:
The linked value literal is repeated across the codebase multiple times.
Example:
33uint256 internal constant _ONE_MILLION = 1_000_000;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 (71cda4ccfd):
The Evergon Labs team evaluated this recommendation to be invalid due to the constant appearing once across the codebase, however, the same value is present in the LendingOracleFacetStorage implementation rendering it to remain valid albeit open and thus acknowledged.
Alleviation (d7b20c134f):
The constant literal has been relocated to a contract-level declaration within the GeneralStorage common dependency, addressing this exhibit.
