Summary
TokenDivider::divideNft Allows Multiple ERC20 Token Deployments for Same NFT Leading to State Inconsistencies
Vulnerability Details
In the TokenDivider::divideNft function, a new ERC20 token contract is deployed each time the function is called, even for the same NFT. This can lead to a serious issue where newer token deployments overwrite the previous mappings in nftToErc20Info and erc20ToNft, potentially causing loss of user funds and state inconsistencies.
Impact
This vulnerability can result in:
- Loss of track of previously minted ERC20 tokens 
- Users unable to locate or claim their tokens from previous fractionalization 
- State inconsistencies in the protocol 
- Potential permanent loss of user funds locked in old ERC20 contracts 
Proof of Concept: Add the following test to demonstrate the vulnerability:
function testMultipleErc20DeploymentsForSameNft() public {
    vm.startPrank(USER);
    ERC721Mock(erc721Mock).approve(address(tokenDivider), 0);
    
    tokenDivider.divideNft(address(erc721Mock), 0, AMOUNT);
    address firstErc20 = tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address;
    
    vm.startPrank(address(tokenDivider));
    ERC721Mock(erc721Mock).safeTransferFrom(address(tokenDivider), USER, 0);
    vm.stopPrank();
    
    vm.startPrank(USER);
    ERC721Mock(erc721Mock).approve(address(tokenDivider), 0);
    
    tokenDivider.divideNft(address(erc721Mock), 0, AMOUNT);
    address secondErc20 = tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address;
    
    assertFalse(firstErc20 == secondErc20);
    
    ERC20Mock firstErc20Mock = ERC20Mock(firstErc20);
    uint256 lostTokens = firstErc20Mock.balanceOf(USER);
    assertEq(lostTokens, AMOUNT);
    
    firstErc20Mock.approve(address(tokenDivider), AMOUNT);
    vm.expectRevert();
    tokenDivider.claimNft(address(erc721Mock));
    vm.stopPrank();
}
Tools Used
Foundry
Recommendations
    function divideNft(address nftAddress, uint256 tokenId, uint256 amount) onlyNftOwner(nftAddress, tokenId) external {
        if(nftAddress == address(0)) { revert TokenDivider__NftAddressIsZero(); }
        if(amount == 0) { revert TokenDivider__AmountCantBeZero(); }
+       if(nftToErc20Info[nftAddress].erc20Address != address(0)) {
+           revert TokenDivider__NftAlreadyFractionalized();
+       }
        ERC20ToGenerateNftFraccion erc20Contract = new ERC20ToGenerateNftFraccion(
            string(abi.encodePacked(ERC721(nftAddress).name(), "Fraccion")), 
            string(abi.encodePacked("F", ERC721(nftAddress).symbol())));
        // Rest of the function remains the same
    }