positionIsClosed == true, it uses raw ERC20 token balances, exposing the system to manipulation through direct token transfers to the contract. When positionIsClosed == false, it uses _totalAmount(prices), which still incorporates token balances that can be manipulated. These dual valuation methods create vulnerabilities that can be exploited to either dilute share allocation or force users to overpay for shares.Manipulable Token Balance Calculations: When the vault is closed, share calculation relies directly on balanceOf(address(this)), allowing attackers to artificially inflate the vault's apparent value by transferring tokens directly to the contract, causing new depositors to receive fewer shares than deserved.
Inconsistent Valuation Methods: The contract switches between two different calculation methods depending on vault state, creating opportunities for exploitation during state transitions.
Manipulation of _totalAmount(prices): Even in the open position state, the valuation includes current token balances through IERC20(indexToken).balanceOf(address(this)) and collateralToken.balanceOf(address(this)), making both calculation pathways susceptible to similar attacks.
Lack of Robust Asset Tracking: The contract fails to properly track assets that should be included in share calculations, instead relying on potentially manipulable on-chain balances.
Share Dilution: Attackers can reduce the shares new depositors receive by inflating the apparent vault value, effectively stealing value from new participants.
Overcharging Depositors: Users may need to deposit more assets than fair to receive an appropriate share when token balances are manipulated.
Protocol Destabilization: The inconsistent and manipulable share valuation undermines the fundamental economic model of the vault, potentially leading to user exodus and protocol failure.
Manual review
Implement internal accounting to track legitimate deposits and use these tracked values, not on-chain balances, for share calculations.
Prevent tokens from getting stuck. This is a simple donation to every shareholder, and therefore, every share has more value (profit), leading to fewer shares for future users. If this is not intended by the user, it is merely a mistake! For totalAmountBefore > amount * totalShares, Here is the worst-case scenario (with the minimum amount): first deposit 0.001000 (e4) USDC → 1e12 shares. Second deposit: 0.001 (e4) USDC * 1e12 / 0.001 (e4) USDC. So, the attacker would need to donate 1e16 tokens, meaning 1e10 USDC → 10 billion $. Even in the worst case, it's informational.
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.