Omniscia Arcade XYZ Audit

LoanLibrary Code Style Findings

LoanLibrary Code Style Findings

LLY-01C: Inefficient Tight Packing of Structs

Description:

The LoanTerms and LoanTermsWithItems structs defined within LoanLibrary specify that they are meant to tight-pack their variables, however, they are packed inefficiently. In detail, two uint32 variables are packed with a uint160 variable whilst the struct contains two address types (represented by 160-bits) that occupy a full slot.

Example:

contracts/libraries/LoanLibrary.sol
29/**
30 * @dev The raw terms of a loan.
31 */
32struct LoanTerms {
33 /// @dev Packed variables
34 // The number of seconds representing relative due date of the loan.
35 /// @dev Max is 94,608,000, fits in 32 bits
36 uint32 durationSecs;
37 // Timestamp for when signature for terms expires
38 uint32 deadline;
39 // Interest expressed as a rate, unlike V1 gross value.
40 // Input conversion: 0.01% = (1 * 10**18) , 10.00% = (1000 * 10**18)
41 // This represents the rate over the lifetime of the loan, not APR.
42 // 0.01% is the minimum interest rate allowed by the protocol.
43 /// @dev Max is 10,000%, fits in 160 bits
44 uint160 proratedInterestRate;
45 /// @dev Full-slot variables
46 // The amount of principal in terms of the payableCurrency.
47 uint256 principal;
48 // The token ID of the address holding the collateral.
49 /// @dev Can be an AssetVault, or the NFT contract for unbundled collateral
50 address collateralAddress;
51 // The token ID of the collateral.
52 uint256 collateralId;
53 // The payable currency for the loan principal and interest.
54 address payableCurrency;
55 // Affiliate code used to start the loan.
56 bytes32 affiliateCode;
57}

Recommendation:

We advise the proratedInterestRate to be up-cast to 256 bits and the two uint32 variables to be relocated after each address member.

Additionally, we advise the uint32 variables to be upcast to uint96 ensuring that they occupy a full slot when paired with an address type to prevent data corruption in future updates.

Regardless of the upcast operations, relocating the uint32 variables will lead to a reduction of one storage slot in each struct.

As a final note, we would like to specify that the LoanData could also be refactored to tight-pack the FeeSnapshot and LoanTerms entries via a new struct declaration (i.e. LoanTermsWithFeeSnapshot).

Alleviation (7a4e1dc948e94ded7385dbb74818bcf93ecc207c):

The recommended course of action has been applied properly, ensuring that the address members are optimally packed with the relevant sub-256 bit variables and that the proratedInterestRate is increased in accuracy whilst reducing the overall storage footprint of the referenced structs.