MEDIUM severity: Idle balance is computed incorrectly when an incorrect vault fee is specified. **Description:** When a new deposit is made into a Bunni pool in which there is already some liquidity, the amounts of each token to deposit are computed based on the current ratio. It is assumed by the current logic that that the idle amount can only increase proportionally to the current balance.....

Vulnerable code:
contract ERC4626FeeMock is ERC4626 {
    address internal immutable _asset;
    uint256 public fee;
    uint256 internal constant MAX_FEE = 10000;

    constructor(IERC20 asset_, uint256 _fee) {
        _asset = address(asset_);
        if(_fee > MAX_FEE) revert();
        fee = _fee;
    }

    function setFee(uint256 newFee) external {
        if(newFee > MAX_FEE) revert();
        fee = newFee;
    }

    function deposit(uint256 assets, address to) public override returns (uint256 shares) {
        return super.deposit(assets - assets * fee / MAX_FEE, to);
    }

    function asset() public view override returns (address) {
        return _asset;
    }

    function name() public pure override returns (string memory) {
        return "MockERC4626";
    }

    function symbol() public pure override returns (string memory) {
        return "MOCK-ERC4626";
    }
}

--  import {ERC4626Mock} from "./mocks/ERC4626Mock.sol";
++  import {ERC4626Mock, ERC4626FeeMock} from "./mocks/ERC4626Mock.sol";

function test_WrongIdleBalanceComputation() public {
        ILiquidityDensityFunction uniformDistribution = new UniformDistribution(address(hub), address(bunniHook), address(quoter));
        Currency currency0 = Currency.wrap(address(token0));
        Currency currency1 = Currency.wrap(address(token1));
        ERC4626FeeMock feeVault0 = new ERC4626FeeMock(token0, 0);
        ERC4626 vault0_ = ERC4626(address(feeVault0));
        ERC4626 vault1_ = ERC4626(address(0));
        IBunniToken bunniToken;
        PoolKey memory key;
        (bunniToken, key) = hub.deployBunniToken(
            IBunniHub.DeployBunniTokenParams({
                currency0: currency0,
                currency1: currency1,
                tickSpacing: TICK_SPACING,
                twapSecondsAgo: TWAP_SECONDS_AGO,
                liquidityDensityFunction: uniformDistribution,
                hooklet: IHooklet(address(0)),
                ldfType: LDFType.DYNAMIC_AND_STATEFUL,
                ldfParams: bytes32(abi.encodePacked(ShiftMode.STATIC, int24(-5) * TICK_SPACING, int24(5) * TICK_SPACING)),
                hooks: bunniHook,
                hookParams: abi.encodePacked(
                    FEE_MIN,
                    FEE_MAX,
                    FEE_QUADRATIC_MULTIPLIER,
                    FEE_TWAP_SECONDS_AGO,
                    POOL_MAX_AMAMM_FEE,
                    SURGE_HALFLIFE,
                    SURGE_AUTOSTART_TIME,
                    VAULT_SURGE_THRESHOLD_0,
                    VAULT_SURGE_THRESHOLD_1,
                    REBALANCE_THRESHOLD,
                    REBALANCE_MAX_SLIPPAGE,
                    REBALANCE_TWAP_SECONDS_AGO,
                    REBALANCE_ORDER_TTL,
                    true, // amAmmEnabled
                    ORACLE_MIN_INTERVAL,
                    MIN_RENT_MULTIPLIER
                ),
                vault0: vault0_,
                vault1: vault1_,
                minRawTokenRatio0: 0.20e6,
                targetRawTokenRatio0: 0.30e6,
                maxRawTokenRatio0: 0.40e6,
                minRawTokenRatio1: 0,
                targetRawTokenRatio1: 0,
                maxRawTokenRatio1: 0,
                sqrtPriceX96: TickMath.getSqrtPriceAtTick(0),
                name: bytes32("BunniToken"),
                symbol: bytes32("BUNNI-LP"),
                owner: address(this),
                metadataURI: "metadataURI",
                salt: bytes32(0)
            })
        );

        // make initial deposit to avoid accounting for MIN_INITIAL_SHARES
        uint256 depositAmount0 = 1e18 + 1;
        uint256 depositAmount1 = 1e18 + 1;
        address firstDepositor = makeAddr("firstDepositor");
        vm.startPrank(firstDepositor);
        token0.approve(address(PERMIT2), type(uint256).max);
        token1.approve(address(PERMIT2), type(uint256).max);
        PERMIT2.approve(address(token0), address(hub), type(uint160).max, type(uint48).max);
        PERMIT2.approve(address(token1), address(hub), type(uint160).max, type(uint48).max);
        vm.stopPrank();

        // mint tokens
        _mint(key.currency0, firstDepositor, depositAmount0 * 100);
        _mint(key.currency1, firstDepositor, depositAmount1 * 100);

        // deposit tokens
        IBunniHub.DepositParams memory depositParams = IBunniHub.DepositParams({
            poolKey: key,
            amount0Desired: depositAmount0,
            amount1Desired: depositAmount1,
            amount0Min: 0,
            amount1Min: 0,
            deadline: block.timestamp,
            recipient: firstDepositor,
            refundRecipient: firstDepositor,
            vaultFee0: 0,
            vaultFee1: 0,
            referrer: address(0)
        });

        vm.startPrank(firstDepositor);
            (uint256 sharesFirstDepositor, uint256 firstDepositorAmount0In, uint256 firstDepositorAmount1In) = hub.deposit(depositParams);
            console.log("Amount 0 deposited by first depositor", firstDepositorAmount0In);
            console.log("Amount 1 deposited by first depositor", firstDepositorAmount1In);
            console.log("Total supply shares", bunniToken.totalSupply());
        vm.stopPrank();

        IdleBalance idleBalanceBefore = hub.idleBalance(key.toId());
        (uint256 idleAmountBefore, bool isToken0Before) = IdleBalanceLibrary.fromIdleBalance(idleBalanceBefore);
        feeVault0.setFee(1000);     // 10% fee

        depositAmount0 = 1e18;
        depositAmount1 = 1e18;
        address secondDepositor = makeAddr("secondDepositor");
        vm.startPrank(secondDepositor);
        token0.approve(address(PERMIT2), type(uint256).max);
        token1.approve(address(PERMIT2), type(uint256).max);
        PERMIT2.approve(address(token0), address(hub), type(uint160).max, type(uint48).max);
        PERMIT2.approve(address(token1), address(hub), type(uint160).max, type(uint48).max);
        vm.stopPrank();

        // mint tokens
        _mint(key.currency0, secondDepositor, depositAmount0);
        _mint(key.currency1, secondDepositor, depositAmount1);

        // deposit tokens
        depositParams = IBunniHub.DepositParams({
            poolKey: key,
            amount0Desired: depositAmount0,
            amount1Desired: depositAmount1,
            amount0Min: 0,
            amount1Min: 0,
            deadline: block.timestamp,
            recipient: secondDepositor,
            refundRecipient: secondDepositor,
            vaultFee0: 0,
            vaultFee1: 0,
            referrer: address(0)
        });

        vm.prank(secondDepositor);
        (uint256 sharesSecondDepositor, uint256 secondDepositorAmount0In, uint256 secondDepositorAmount1In) = hub.deposit(depositParams);
        console.log("Amount 0 deposited by second depositor", secondDepositorAmount0In);
        console.log("Amount 1 deposited by second depositor", secondDepositorAmount1In);

        logBalances(key);
        console.log("Total shares afterwards", bunniToken.totalSupply());
        IdleBalance idleBalanceAfter = hub.idleBalance(key.toId());
        (uint256 idleAmountAfter, bool isToken0After) = IdleBalanceLibrary.fromIdleBalance(idleBalanceAfter);
        console.log("Idle balance before", idleAmountBefore);
        console.log("Is idle balance in token0 before?", isToken0Before);
        console.log("Idle balance after", idleAmountAfter);
        console.log("Is idle balance in token0 after?", isToken0Before);
    }