Increasing Length Array as Loop Variable vulnerability inside VaultControllerStrategy
. This issue arises from an unbounded loop that iterates over the vaults
array without any constraints on its size. As the vaults
array can continuously grow without a mechanism to decrease its length, the loop's gas consumption can become unmanageable. This presents a risk of transaction failures due to gas limit exceedance, potentially leading to a denial of service (DoS) as the number of vaults increases over time.
The vulnerability is in the VaultControllerStrategy.sol
.
The loop uses vaults.length
as its terminating condition. Since the vaults
array is dynamic and can only grow (with no mechanism to remove elements), the length of the array will perpetually increase as more vaults are added. As transactions invoking this loop become more expensive, users may be unable to execute critical functions within the contract, effectively rendering the contract's functionality unusable. Functions relying on this loop may behave unpredictably. For instance, some users might successfully execute transactions if they forward sufficient gas, while others may consistently fail, leading to inconsistent contract behavior.
Consider a scenario where the VaultControllerStrategy
manages numerous vaults. Each addition of a new vault increases the size of the vaults
array. Functions that need to iterate over all vaults to perform operations (e.g., distributing rewards, auditing vault states) will have their gas costs escalate with each new vault. Over time, these operations may become so gas-intensive that they exceed the blockchain's gas limits, preventing successful execution and degrading the contract's utility.
As the number of vaults increases, functions containing the unbounded loop may consume excessive gas, leading to transaction failures. This can prevent users from performing essential operations, effectively halting the contract's functionality. Critical functions may become inaccessible, preventing users from interacting with the contract as intended. This can result in financial losses, especially if users are unable to withdraw funds or perform necessary actions in a timely manner. If core functionalities rely on iterating over all vaults, the entire contract's operations could become non-functional once the vaults
array grows beyond a manageable size.
The VaultManager contract stores all vault addresses in an array called vaults
. Critical functions, like distributeRewards()
, iterate over this array to perform operations on each vault. As new vaults are created, they are added to this array, which can grow indefinitely.
This attack results in a Denial of Service (DoS) for critical protocol functions. Users cannot receive rewards, administrators cannot perform necessary operations across all vaults, and the protocol's functionality is severely impaired.
manual code review
Implement pagination in functions that iterate over vaults. You could use mappings instead of arrays for vault storage and implement a mechanism to remove inactive or empty vaults.
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.