MEDIUM severity: Missing duplicate Incentive Logic can result in Incentive System accounting being broken. **Description:** `IncentiveManager::addIncentiveLogic` allows the owner to add a new Incentive Logic to the list of Incentive Systems:

Once added by the owner, an Incentive Logic can call `IncentiveManager::addPoolIncentiveSystem`:

Given that there is no duplicate validation in...

Vulnerable code:
function addIncentiveLogic(address logic) external onlyOwner {
    uint256 _index = nextIncentiveIndex;
    incentiveSystems[_index] = IncentiveSystem(logic, IIncentiveLogic(logic).updateOnSwap());
    incentiveSystemIndex[logic] = _index;
    nextIncentiveIndex++;

    emit NewIncentiveLogic(_index, logic);
}

function addPoolIncentiveSystem(IncentivizedPoolId id) external onlyIncentiveLogics {
    uint256 _systemId = incentiveSystemIndex[msg.sender];
    if (poolListedIncentiveSystems[id][_systemId]) return;
    poolIncentiveSystems[id].push(_systemId);
    poolListedIncentiveSystems[id][_systemId] = true;
}

function test_addDuplicateIncentiveLogic() public {
    manager.addHook(address(hook1));
    hook1.notifyInitialize(pool1, lpToken1);
    hook1.notifyInitialize(pool2, lpToken2);

    vm.expectEmit(true, true, true, true);
    emit NewIncentiveLogic(1, address(logic1));
    manager.addIncentiveLogic(address(logic1));

    assertEq(manager.incentiveSystemIndex(address(logic1)), 1);

    assertEq(manager.poolListedIncentiveSystems(id1, 1), false);
    assertEq(manager.poolListedIncentiveSystems(id1, 2), false);

    logic1.addPoolIncentiveSystem(address(manager), id1);

    assertEq(manager.poolListedIncentiveSystems(id1, 1), true);
    assertEq(manager.poolListedIncentiveSystems(id1, 2), false);

    vm.expectEmit(true, true, true, true);
    emit NewIncentiveLogic(2, address(logic1));
    manager.addIncentiveLogic(address(logic1));

    assertEq(manager.incentiveSystemIndex(address(logic1)), 2);

    assertEq(manager.poolListedIncentiveSystems(id1, 1), true);
    assertEq(manager.poolListedIncentiveSystems(id1, 2), false);

    logic1.addPoolIncentiveSystem(address(manager), id1);

    assertEq(manager.poolListedIncentiveSystems(id1, 1), true);
    assertEq(manager.poolListedIncentiveSystems(id1, 2), true);

    (address system1, bool updateOnSwap1) = manager.incentiveSystems(1);
    assertEq(system1, address(logic1));
    assertEq(updateOnSwap1, false);

    (address system2, bool updateOnSwap2) = manager.incentiveSystems(2);
    assertEq(system2, address(logic1));
    assertEq(updateOnSwap2, false);


    int256 amount = int256(10 ether);

    uint256 prev_balance = logic1.userBalances(id1, user1);
    uint256 prev_user_liquidity = manager.poolUserLiquidity(id1, user1);
    uint256 prev_total_liquidity = manager.poolTotalLiquidity(id1);

    vm.expectEmit(true, true, true, true);
    emit LiquidityChange(id1, address(0), user1, uint256(amount));

    hook1.notifyAddLiquidty(pool1, lpToken1, user1, amount);

    uint256 new_balance = logic1.userBalances(id1, user1);
    uint256 new_user_liquidity = manager.poolUserLiquidity(id1, user1);
    uint256 new_total_liquidity = manager.poolTotalLiquidity(id1);

    assertEq(new_balance, prev_balance + uint256(amount));

    assertEq(new_user_liquidity, prev_user_liquidity + uint256(amount));
    assertEq(new_total_liquidity, prev_total_liquidity + uint256(amount));

    assertEq(manager.getPoolTotalLiquidity(id1), new_total_liquidity);
    assertEq(manager.getPoolUserLiquidity(id1, user1), new_user_liquidity);
}