Omniscia Arcade XYZ Audit
LoanLibrary Code Style Findings
LoanLibrary Code Style Findings
LLY-01C: Inefficient Tight Packing of Structs
Type | Severity | Location |
---|---|---|
Gas Optimization | ![]() | LoanLibrary.sol:L36, L38, L44, L50, L54 |
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:
29/**30 * @dev The raw terms of a loan.31 */32struct LoanTerms {33 /// @dev Packed variables34 // The number of seconds representing relative due date of the loan.35 /// @dev Max is 94,608,000, fits in 32 bits36 uint32 durationSecs;37 // Timestamp for when signature for terms expires38 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 bits44 uint160 proratedInterestRate;45 /// @dev Full-slot variables46 // 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 collateral50 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.