HIGH severity: `UpdateWeightRunner::performUpdate` reverts on underflow when new multiplier is zero. **Description:** In [`UpdateWeightRunner::_calculateMultiplerAndSetWeights`](https://github.com/QuantAMMProtocol/QuantAMM-V1/blob/7213401491f6a8fd1fcc1cf4763b15b5da355f1c/pkg/pool-quantamm/contracts/UpdateWeightRunner.sol#L433-L504), the new multiplier is determined by calculating the [change in...

Vulnerable code:
int256 currentLastInterpolationPossible = type(int256).max;

for (uint i; i < local.currentWeights.length; ) {
    // ...

    if (blockMultiplier > int256(0)) {
        weightBetweenTargetAndMax = upperGuardRail - local.currentWeights[i];
        // ...
        blockTimeUntilGuardRailHit = weightBetweenTargetAndMax / blockMultiplier;
    } else if (blockMultiplier == int256(0)) {
        blockTimeUntilGuardRailHit = type(int256).max; // @audit if blockMultiplier is 0 this is max
    } else {
        weightBetweenTargetAndMax = local.currentWeights[i] - local.absoluteWeightGuardRail18;
        // ...
        blockTimeUntilGuardRailHit = weightBetweenTargetAndMax / int256(uint256(-1 * blockMultiplier));
    }
    // ...
}
// ...

//next expected update + time beyond that
currentLastInterpolationPossible += int40(uint40(block.timestamp));

function testUpdatesFailsWhenMultiplierIsZero() public {
    vm.startPrank(owner);
    updateWeightRunner.setApprovedActionsForPool(address(mockPool), 3);
    vm.stopPrank();
    int256[] memory initialWeights = new int256[](4);
    initialWeights[0] = 0;
    initialWeights[1] = 0;
    initialWeights[2] = 0;
    initialWeights[3] = 0;

    // Set initial weights
    mockPool.setInitialWeights(initialWeights);

    int216 fixedValue = 1000;
    chainlinkOracle = deployOracle(fixedValue, 3601);

    vm.startPrank(owner);
    updateWeightRunner.addOracle(OracleWrapper(chainlinkOracle));
    vm.stopPrank();

    vm.startPrank(address(mockPool));

    address[][] memory oracles = new address[][](1);
    oracles[0] = new address[](1);
    oracles[0][0] = address(chainlinkOracle);

    uint64[] memory lambda = new uint64[](1);
    lambda[0] = 0.0000000005e18;
    updateWeightRunner.setRuleForPool(
        IQuantAMMWeightedPool.PoolSettings({
            assets: new IERC20[](0),
            rule: IUpdateRule(mockRule),
            oracles: oracles,
            updateInterval: 1,
            lambda: lambda,
            epsilonMax: 0.2e18,
            absoluteWeightGuardRail: 0.2e18,
            maxTradeSizeRatio: 0.2e18,
            ruleParameters: new int256[][](0),
            poolManager: addr2
        })
    );
    vm.stopPrank();

    vm.startPrank(addr2);
    updateWeightRunner.InitialisePoolLastRunTime(address(mockPool), 1);
    vm.stopPrank();

    vm.warp(block.timestamp + 10000000);
    mockRule.CalculateNewWeights(
        initialWeights,
        new int256[](0),
        address(mockPool),
        new int256[][](0),
        new uint64[](0),
        0.2e18,
        0.2e18
    );
    vm.expectRevert();
    updateWeightRunner.performUpdate(address(mockPool));
}

//next expected update + time beyond that
+ if(currentLastInterpolationPossible < int256(type(int40).max)) {
      currentLastInterpolationPossible += int40(uint40(block.timestamp));
+ }