The function getUserDeposits in PerpetualVault returns all deposit IDs stored in an EnumerableSet by iterating over its entire length.
If a user has accumulated a very large number of deposits, this iteration may consume excessive gas, exceeding block limits.
The code implementation is as follows:
Because there is no pagination or limit on the number of iterations, a user with thousands—or tens of thousands—of deposits may trigger an iteration that uses more gas than is available in a single block. Although this is a view function (and thus not directly subject to state‑changing gas limits when called off‑chain), if used in on‑chain calls (or indirectly by keepers or UIs that call it as part of a transaction), it could revert or become prohibitively expensive.
A user makes 10,000 separate deposits over time, resulting in an EnumerableSet containing 10,000 deposit IDs.
When a call to getUserDeposits(user)
is made, the function attempts to allocate and populate an array with 10,000 elements.
Even if this function is only used by off‑chain interfaces, an attacker could deliberately spam deposits to cause a legitimate user’s deposit list to grow excessively large, causing subsequent calls to exceed gas limits (especially if used in conjunction with on‑chain processes).
The function fails (or reverts) due to gas exhaustion, preventing retrieval of deposit data and disrupting any dependent user interface or automation.
Frontend applications and off‑chain services may be unable to retrieve deposit data for users with many deposits.
Manual Review
Modify the function to return deposits in pages (with a defined start index and limit) so that no single call iterates over an unbounded number of elements.
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
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.