Omniscia Arcade XYZ Audit
LoanCore Code Style Findings
LoanCore Code Style Findings
LCE-01C: Ineffectual Usage of Safe Arithmetics
| Type | Severity | Location |
|---|---|---|
| Language Specific | ![]() | LoanCore.sol:L176, L415, L569, L666, L702 |
Description:
The linked mathematical operations are guaranteed to be performed safely by surrounding conditionals evaluated in either require checks or if-else constructs.
Example:
169// Check that we will not net lose tokens170if (_amountToBorrower > _amountFromLender) revert LC_CannotSettle(_amountToBorrower, _amountFromLender);171
172// Mark collateral as escrowed173collateralInUse[collateralKey] = true;174
175// Assign fees for withdrawal176uint256 feesEarned = _amountFromLender - _amountToBorrower;Recommendation:
Given that safe arithmetics are toggled on by default in pragma versions of 0.8.X, we advise the linked statements to be wrapped in unchecked code blocks thereby optimizing their execution cost.
Alleviation (0a7551b095ee0dc4fb2a56d2267e05472128cf0e):
The unchecked code blocks have been introduced to all referenced calculations, addressing this exhibit in full.
LCE-02C: Inefficient Loop Limit Evaluation
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | LoanCore.sol:L521 |
Description:
The linked for loop evaluates its limit inefficiently on each iteration.
Example:
521for (uint256 i = 0; i < borrowerNote.balanceOf(caller); i++) {Recommendation:
We advise the statements within the for loop limit to be relocated outside to a local variable declaration that is consequently utilized for the evaluation to significantly reduce the codebase's gas cost. We should note the same optimization is applicable for storage reads present in such limits as they are newly read on each iteration (i.e. length members of arrays in storage).
Alleviation (7a4e1dc948e94ded7385dbb74818bcf93ecc207c):
The loop's length is now properly calculated in a dedicated variable outside the for loop (noteCount), ensuring that the loop's limit evaluation code is significantly more optimal and thus addressing this exhibit.
LCE-03C: Inefficient mapping Lookups
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | LoanCore.sol:L180, L181, L313, L314, L355, L356, L422, L423, L501, L527, L528, L566, L569, L588, L589, L671, L672, L713, L715 |
Description:
The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.
Example:
180feesWithdrawable[terms.payableCurrency][address(this)] += protocolFee;181feesWithdrawable[terms.payableCurrency][affiliate] += affiliateFee;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.
Alleviation (7a4e1dc948):
The exhibit has been partially alleviated as multiple mapping lookup pairs have not been optimized (L180 + L181, L566 + L569, L588 + L589, L713 + L715) and certain optimizations were incorrectly applied by using memory instead of storage pointers (L501, L527 + L528).
Alleviation (0a7551b095):
The remaining highlighted exhibits apart from the first one were properly optimized and the memory pointers changed to storage. Given that the L180 + L181 instance is conditional, the optimization would work solely in a worst-case scenario and as such we consider it to be up to the Arcade XYZ team's discretion.
As such, we consider this exhibit fully alleviated.
LCE-04C: Loop Iterator Optimizations
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | LoanCore.sol:L521, L611 |
Description:
The linked for loops increment / decrement their iterator "safely" due to Solidity's built - in safe arithmetics (post-0.8.X).
Example:
521for (uint256 i = 0; i < borrowerNote.balanceOf(caller); 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 (7a4e1dc948e94ded7385dbb74818bcf93ecc207c):
All referenced iterator optimizations have been applied, addressing this exhibit in full.
LCE-05C: Optimization of Assignments
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | LoanCore.sol:L180-L181, L313-L314, L355-L356, L422-L423, L671-L672 |
Description:
The referenced assignments are performed unconditionally when they may result in a zero-value increment.
Example:
180feesWithdrawable[terms.payableCurrency][address(this)] += protocolFee;181feesWithdrawable[terms.payableCurrency][affiliate] += affiliateFee;Recommendation:
We advise them to be performed conditionally akin to transfers, optimizing the gas cost of the function significantly under certain cases.
Alleviation (7a4e1dc948e94ded7385dbb74818bcf93ecc207c):
All referenced assignments are now properly performed solely when the values that are being added to the existing data entries are non-zero, optimizing each assignment's worst-case gas cost significantly.
LCE-06C: Suboptimal Struct Declaration Style
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | LoanCore.sol:L263 |
Description:
The linked declaration style of a struct is using index-based argument initialization.
Example:
263noteReceipts[loanId] = NoteReceipt(data.terms.payableCurrency, _amountToLender);Recommendation:
We advise the key-value declaration format to be utilized instead, greatly increasing the legibility of the codebase.
Alleviation (7a4e1dc948e94ded7385dbb74818bcf93ecc207c):
The structure's instantiation has been replaced by the key-value declaration style, optimizing its legibility greatly.
