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.