The perpVault contract calculates shares to be minted using balanceOf(address(this)). This method allows a malicious user to inflate the share price by transferring extra collateral directly to the contract, leading to an inflation attack.
After pool creation, a malicious user deposits collateral via the deposit() function. Due to the minimum deposit amount, the user deposits 1000 USDC and mints (1000 * 1e6 * 1e8) shares.
Subsequently, a malicious user transfers an additional 1000 USDC directly to the contract. The contract's balance becomes 2000 USDC while totalShares remains at 1000e14.
When a new user later deposits 1000 USDC, they expect to receive shares proportional to their deposit(1000e14). However, because the share price is now inflated by the extra collateral, the new user only receives 500e14 shares. This results in totalShares equaling 1500e14 and totalDeposit being 2000 USDC.
Over a week, when withdrawals occur, the malicious user can withdraw their shares and receive tokens, for example, 1333.33 USDC (simplified calculation, not considering the pnl of position), thereby profiting by approximately 333.33 USDC.
The major problem is that this does not need to be done at the starting of the pool creation but when all the withdrawers withdraw their shares after that also malicious users can perform this attack.
Malicious users can profit at the expense of new depositors by artificially inflating the share price.
Manual code review
Track the totalDeposit during the deposit flow and use this value for share calculation instead of using balanceOf(address(this)).
This change will ensure that extra collateral transferred directly to the contract does not artificially inflate the share price, thereby preventing the inflation attack.
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.