Because the contract never checks whether _leverage
is within the documented “3x max” range, an owner or deployment script can set dangerously high leverage values, contradicting user expectations and risking catastrophic position liquidations. Adding a simple require-statement or logic check ensures that the vault stays within the intended maximum leverage.
FIX -> Enforce Maximum Leverage in initialize()
RootCause & Where It Happens
Within initialize()
:
The documentation (and presumably user expectations) specify:
“Vault leverage = Max leverage will be 3x leverage.”
However, as it seems clear the contract does not validate _leverage
. The code simply sets the vault’s leverage
to whatever value is passed in. This means leverage
could be far above 30000 basis points (the internal code representation of 3x), resulting in an extremely high-risk vault or even systematically unsafe conditions.
The Problem is summarized in ->
The owner or deployment script might mistakenly set leverage to a very large value (e.g., 100x) despite the doc specifying a 3x maximum.
If user depositors rely on the 3x limit for their risk assumptions, they could unknowingly deposit into a vault with higher leverage, potentially facing near-instant liquidation in volatile markets.
There is no on-chain safeguard or revert that ensures leverage <= 3x. This is a direct discrepancy with the stated “Max leverage will be 3x.”
Impact
Medium to High severity because it breaks a fundamental user assumption about risk exposure. If the vault is inadvertently set to 10x or 50x, depositors can suffer large, unexpected losses.
Could lead to reputational harm if the vault is advertised as “up to 3x,” yet is actually configured for far higher leverage.
Recommended Remediation
Enforce Maximum Leverage in initialize()
For example:
That ensures the contract reverts if an out-of-bounds leverage is passed in.
Add a Setter Check if Leverage Is Updatable
If there is a function that changes leverage
post-initialization, also apply the same check.
Document or Remove the 3x Limit
If the protocol truly wants to allow higher leverage, the doc should reflect the actual limit. Otherwise, the code must enforce the stated maximum.
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. Keepers are added by the admin, there is no "malicious keeper" and if there is a problem in those keepers, that's out of scope. ReadMe and known issues states: " * System relies heavily on keeper for executing trades * Single keeper point of failure if not properly distributed * Malicious keeper could potentially front-run or delay transactions * Assume that Keeper will always have enough gas to execute transactions. There is a pay execution fee function, but the assumption should be that there's more than enough gas to cover transaction failures, retries, etc * There are two spot swap functionalies: (1) using GMX swap and (2) using Paraswap. We can assume that any swap failure will be retried until success. " " * Heavy dependency on GMX protocol functioning correctly * Owner can update GMX-related addresses * Changes in GMX protocol could impact system operations * We can assume that the GMX keeper won't misbehave, delay, or go offline. " "Issues related to GMX Keepers being DOS'd or losing functionality would be considered invalid."
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. Keepers are added by the admin, there is no "malicious keeper" and if there is a problem in those keepers, that's out of scope. ReadMe and known issues states: " * System relies heavily on keeper for executing trades * Single keeper point of failure if not properly distributed * Malicious keeper could potentially front-run or delay transactions * Assume that Keeper will always have enough gas to execute transactions. There is a pay execution fee function, but the assumption should be that there's more than enough gas to cover transaction failures, retries, etc * There are two spot swap functionalies: (1) using GMX swap and (2) using Paraswap. We can assume that any swap failure will be retried until success. " " * Heavy dependency on GMX protocol functioning correctly * Owner can update GMX-related addresses * Changes in GMX protocol could impact system operations * We can assume that the GMX keeper won't misbehave, delay, or go offline. " "Issues related to GMX Keepers being DOS'd or losing functionality would be considered invalid."
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.