Within the LendingPool contract, certain functions rely on iterating over a potentially large array of deposited NFT token IDs. Each iteration requires computing or fetching the price of each NFT, resulting in gas costs that scale with the array’s size. In extreme cases—such as when a malicious user deposits hundreds or thousands of low-value NFTs—essential processes like liquidation checks or collateral valuation become prohibitively expensive or impossible, effectively leading to a Denial of Service. This vulnerability compromises the reliability of the entire protocol and can block or severely hinder normal user operations.
The core issue arises from functions within the LendingPool contract that iterate over an array storing all deposited NFT token IDs (user.nftTokenIds). If a user deposits a large number of NFTs, any function dependent on that array (e.g., getUserCollateralValue, calculateHealthFactor, initiateLiquidation) will iterate through each token ID, incurring a gas cost proportional to the size of the array. In a worst-case scenario—such as a malicious actor depositing thousands of low-value NFTs—this can become prohibitively expensive or impossible to execute, effectively leading to a Denial of Service. This situation not only disrupts normal operations for legitimate users but also poses a strategic attack vector that can degrade the protocol’s overall performance and accessibility.
Denial of Service: Excessive gas usage when iterating through a large array of NFTs can make critical operations—such as liquidation checks, collateral valuation, or health factor calculations—unfeasibly expensive or impossible to execute, halting normal protocol functionality.
User Experience Degradation: Even under moderately large arrays of NFTs, legitimate users may face significantly higher transaction costs, reducing usability and discouraging participation in the protocol.
Attack Vector for Malicious Actors: By depositing large numbers of low-value NFTs, an attacker can intentionally inflate gas costs and disrupt essential operations, affecting other users’ ability to manage their positions or withdraw funds in a timely manner.
The functions iterating over user.nftTokenIds can become extremely gas-costly if a user deposits a large number of NFTs. This overconsumption of gas can lead to a Denial of Service scenario, where any function that checks collateral value or initiates liquidation becomes prohibitively expensive or impossible to execute.
Below is a brief snippet highlighting the potential issue of iterating over the NFT array:
( ! ) The issue arises because if user.nftTokenIds.length is large, these loops can consume excessive gas, leading to a potential Denial of Service or prohibitive costs for critical operations like liquidation or collateral valuation.
Reason for the finding: By storing all NFT IDs in a single array and iterating through it, each call to getUserCollateralValue, calculateHealthFactor, or any function that relies on them could become very gas-intensive if the array is large.
Potential Impact:
A malicious user could deposit numerous low-value NFTs to overload and block operations.
Gas block limits might prevent execution if the array is too large.
User experience deteriorates due to high gas fees.
A user repeatedly calls depositNFT, depositing hundreds or thousands of NFTs (e.g., very low-value NFTs).
The array user.nftTokenIds grows excessively.
When the protocol (or any other user) calls calculateHealthFactor, initiateLiquidation, or getUserCollateralValue on this user, the loop processes the entire NFT collection.
The gas cost surges significantly, potentially causing transaction failures or consuming most of the block gas limit, resulting in a Denial of Service.
This test mints 200 NFTs for user1, each assigned a valid price of 10 crvUSD, and deposits them into the LendingPool. By calling getUserCollateralValue and calculateHealthFactor, we confirm the contract iterates through the large NFT array (showing a total collateral value of 2000 crvUSD and a maximum health factor). The test completes in over 4 minutes, demonstrating that iterating over a large array of NFTs significantly increases gas consumption, reinforcing the Denial of Service risk.
Add the following test to test/unit/core/pools/LendingPool/LendingPool.test.js
Note: Run this test only if you have at least 4 minutes available.
Iterating over a large array directly scales with gas consumption. Without limiting the number of NFTs a user can deposit or implementing partial/batch calculations, the functions iterating over user.nftTokenIds can become excessively expensive or even impossible to run, confirming the Denial of Service risk.
Manual Code Review: A comprehensive examination of the contract source code was performed, with particular attention to loops and operations that could lead to high gas consumption.
Limit the Number of NFTs per User: Enforce a maximum cap on deposited NFTs to prevent runaway loop iterations.
Implement Alternative Data Structures: Use more efficient, non-iterative lookups (e.g., mappings) to avoid costly loops for collateral calculations.
LightChaser L-36 and M-02 covers it.
LightChaser L-36 and M-02 covers it.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.