The _mint function in PerpetualVault.sol allocates shares to users based on the current vault value (totalAmountBefore), which fluctuates due to profits or losses from GMX positions. This results in users receiving varying amounts of shares for the same deposit amount depending on the vault's value at the time of deposit. This behavior partially violates the "Depositor Share Value Preservation" invariant outlined in the project documentation, as the value represented by existing depositors' shares can be diluted by new deposits when the vault's value is reduced, leading to an unfair distribution of initial share value.
Location: PerpetualVault.sol, [_mint function](Inconsistent Share Allocation Based on Vault Value Leading to Partial Violation of Depositor Share Value Preservation)
Relevant Code:
Issue: The calculation of _shares uses totalAmountBefore, which represents the vault's current value (including profits/losses from positions). This value can decrease due to losses, causing new users to receive disproportionately more shares relative to their deposit compared to earlier depositors. This behavior conflicts with the "Depositor Share Value Preservation" invariant documented in the project's initial description.
Documentation Reference: The project documentation states: "The value of a depositor's shares should never decrease due to the actions of other depositors. Any losses or gains should be distributed proportionally based on share ownership. There are some exceptions, but there shouldn't be any material loss of depositor's share value." The inconsistent allocation of shares based on fluctuating vault value leads to a material reduction in the relative value of existing depositors' shares when new deposits occur during a loss period, violating this invariant.
Financial Impact: Early depositors may see the relative value of their shares diluted when new users deposit during a period of reduced vault value, receiving more shares per unit of deposit than warranted. This does not result in direct loss of funds but affects the fairness of profit/loss distribution upon withdrawal.
User Trust: The perceived inequity could reduce user confidence in the protocol, potentially deterring participation if depositors feel their share value is unfairly impacted by timing.
Manual Analysis: Reviewed the PerpetualVault.sol source code and the provided project documentation (initial description).
Foundry: Used to simulate the vulnerability and demonstrate its impact through a Proof of Concept.
Setup: User A deposits 1000 USDC when vault empty, receiving 100M shares.
Simulated Loss: Vault value mocked to 500 USDC (50% loss).
User B Deposit: User B deposits 500 USDC and receives 100M shares due to reduced totalAmountBefore.
Result: User B gets the same shares as User A with half the deposit, diluting User A's share value relative to their initial contribution.
Allocate Shares Based on Fixed Initial Deposits:
Use totalDepositAmount (total deposited amount without profit/loss adjustments) instead of totalAmountBefore:
This ensures shares reflect the deposited amount, preserving initial share value.
Normalize with Market Prices:
Adjust totalAmountBefore using prices to normalize vault value against market fluctuations, reducing timing-based inequities.
Document Intent:
If this behavior is intentional, explicitly document it in the project as an exception to the "Depositor Share Value Preservation" invariant, clarifying that share allocation reflects current vault value.
Mitigate Dilution:
Implement a capped share allocation mechanism to limit the impact of vault losses on new depositors, ensuring fairness.
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.