A malicious early user/attacker can manipulate the `AutoPxGlp`'s and `AutoPxGmx`'s' price per share to take an unfair share of future users' deposi
Audit: 2022-11-redactedcartel-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-redactedcartel/blob/main/src/vaults/AutoPxGlp.sol#L304-L322


# Vulnerability details

A well known attack vector for almost all shares based liquidity pool contracts, where an early user can manipulate the price per share and profit from late users' deposits because of the precision loss caused by the rather large value of price per share.
## Impact
Users may suffer loss of a significant portion of the funds they deposited to the Vault.
## Proof of Concept
A malicious early user can `deposit()` with 1 wei of asset token as the first depositor of the PxGLP, and get 1 wei of shares.

Then the attacker can send 10000e18 - 1 of asset tokens and inflate the price per share from 1.0000 to an extreme value of 1.0000e22 ( from (1 + 10000e18 - 1) / 1) .

As a result, the future user who deposits 19999e18 will only receive 1 wei (from 19999e18 * 1 / 10000e18) of shares token.

They will immediately lose 9999e18 or half of their deposits if they `redeem()` right after the `deposit()`.

All external deposit functions lead to this `_deposit()`
```solidity
src/vaults/AutoPxGlp.sol
304:     function _deposit(uint256 assets, address receiver)
305:         internal
306:         returns (uint256 shares)
307:     {
308:         // Check for rounding error since we round down in previewDeposit.
309:         uint256 supply = totalSupply;
310: 
311:         if (
312:             (shares = supply == 0
313:                 ? assets
314:                 : assets.mulDivDown(supply, totalAssets() - assets)) == 0
315:         ) revert ZeroShares();
316: 
317:         _mint(receiver, shares);
318: 
319:         emit Deposit(msg.sender, receiver, assets, shares);
320: 
321:         afterDeposit(receiver, assets, shares);
322:     }
```
First user will get 1 wei of shares for 1 wei of assets because of L313
After manipulations next users will get only 1 wei of shares for 19999e18 of asset  because of `assets.mulDivDown(supply, totalAssets() - assets)`

## Tools Used
Manual Review
## Recommended Mitigation Steps
- Consider requiring a minimal amount of share tokens to be minted for the first minter, and send part of the initial mints as a permanent reserve to the DAO/treasury/deployer so that the pricePerShare can be more resistant to manipulation.
- An alternative is to require only the first depositor to freeze big enough initial amount of liquidity. This approach has been used long enough by various projects, for example in Uniswap V2:
[Uniswap/UniswapV2Pair.sol#L119-L121](https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L119-L121)
- Maybe add a parameter `minSharesOut`, where user can set minimum amount of shares he expects to acquire.
- See how [BalancerV2](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/pool-utils/contracts/BasePool.sol#L307-L325) and [UniswapV2](https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L119-L121) did it. Some MINIMUM a