The VaultReader contract's position size validation fails to properly handle non-zero keys, allowing potential misreporting of position sizes. This could lead to incorrect position calculations and risk management in the perpetual trading system. When a non-zero key is passed, the contract returns potentially invalid position sizes without proper validation. Just like a bank checking account balances, while it correctly shows zero balance for new accounts (key = 0), it fails to properly validate existing account balances (non-zero keys). This creates a disconnect between what the system thinks exists and what actually exists in GMX's storage.
In VaultReader.sol#getPositionSizeInUsd
The flow: arbitrary key → keccak256 hash → dataStore lookup → unchecked return value
The VaultReader contract serves as the eyes of the Perpetual Vault system, responsible for accurately reporting position sizes from GMX. When users deposit USDC to open leveraged positions, the system needs to track these positions reliably. However, there's a critical oversight in how position sizes are validated.
When users deposit USDC to open leveraged positions up to 3x, the system must maintain precise position tracking to protect user funds and manage risk effectively.
The vulnerability emerges in how position sizes are validated. The VaultReader directly passes through GMX storage values without proper bounds checking or validation. This creates a dangerous scenario where the vault could operate with incorrect position sizes, similar to a trading system accepting unverified account balances.
In the real world, this manifests when users interact with leveraged positions. The VaultReader's getPositionSizeInUsd() function blindly trusts GMX storage values
When position sizes exceed expected bounds, the entire risk management system becomes compromised. The vault could:
Allow leverage beyond the protocol's 3x maximum
Miscalculate user share allocations
Incorrectly distribute funding fees
Make flawed position management decisions
The code assumed GMX's dataStore would handle position size validation, but overlooked:
The protocol's position key format requirements (Section 4.2 of GMX docs)
The need for bounds checking on returned values
The potential for malicious position key crafting
Validation should be implemented at multiple levels
There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.
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.