Omniscia Arcade XYZ Audit

LoanCore Code Style Findings

LoanCore Code Style Findings

LCE-01C: Ineffectual Usage of Safe Arithmetics

Description:

The linked mathematical operations are guaranteed to be performed safely by surrounding conditionals evaluated in either require checks or if-else constructs.

Example:

contracts/LoanCore.sol
169// Check that we will not net lose tokens
170if (_amountToBorrower > _amountFromLender) revert LC_CannotSettle(_amountToBorrower, _amountFromLender);
171
172// Mark collateral as escrowed
173collateralInUse[collateralKey] = true;
174
175// Assign fees for withdrawal
176uint256 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

Description:

The linked for loop evaluates its limit inefficiently on each iteration.

Example:

contracts/LoanCore.sol
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

Description:

The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.

Example:

contracts/LoanCore.sol
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

Description:

The linked for loops increment / decrement their iterator "safely" due to Solidity's built - in safe arithmetics (post-0.8.X).

Example:

contracts/LoanCore.sol
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

Description:

The referenced assignments are performed unconditionally when they may result in a zero-value increment.

Example:

contracts/LoanCore.sol
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

TypeSeverityLocation
Code StyleLoanCore.sol:L263

Description:

The linked declaration style of a struct is using index-based argument initialization.

Example:

contracts/LoanCore.sol
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.