MEDIUM severity: `euRetailInvestorsCount` is susceptible to underflow when transferring tokens between retail and qualified investors of the same country on the EU region. **Description:** The root cause of this problem is that a qualified EU investor with tokens on its balance would not increment the `euRetailInvestorsCount` when the investor is downgraded to a retail investor.
This puts the system in an inconsistent state. The qualified investor could've received...

Vulnerable code:
function adjustInvestorsCountsByCountry(
        ...
    ) internal {
        ...
//@audit-info => euRetailInvestorsCount are not modified for Qualified EU Investors
        } else if (countryCompliance == EU && !getRegistryService().isQualifiedInvestor(_id)) {
            if(_increase == CommonUtils.IncDec.Increase) {
                euRetailInvestorsCount[_country]++;
            }
            else {
                euRetailInvestorsCount[_country]--;
            }
        }
        ...
    }

it.only('underflow on euRetailInvestorsCount PoC', async function () {
      const [investor, investor2, usInvestor] = await hre.ethers.getSigners();
      const { dsToken, registryService, complianceService, complianceConfigurationService } = await loadFixture(deployDSTokenRegulated);
      await complianceConfigurationService.setCountryCompliance(INVESTORS.Country.FRANCE, INVESTORS.Compliance.EU);
      await complianceConfigurationService.setEURetailInvestorsLimit(10);
      await registerInvestor(INVESTORS.INVESTOR_ID.INVESTOR_ID_1, investor, registryService);
      await registerInvestor(INVESTORS.INVESTOR_ID.INVESTOR_ID_2, investor2, registryService);
      await registerInvestor(INVESTORS.INVESTOR_ID.US_INVESTOR_ID, usInvestor, registryService);
      await registryService.setCountry(INVESTORS.INVESTOR_ID.INVESTOR_ID_1, INVESTORS.Country.FRANCE);
      await registryService.setCountry(INVESTORS.INVESTOR_ID.INVESTOR_ID_2, INVESTORS.Country.FRANCE);
      await registryService.setCountry(INVESTORS.INVESTOR_ID.US_INVESTOR_ID, INVESTORS.Country.USA);

      //@audit-info => Set investor2 as a qualified investor!
      await registryService.setAttribute(INVESTORS.INVESTOR_ID.INVESTOR_ID_2, 4, 1, 0, 'abcde');

      await dsToken.issueTokens(investor, 500);
      const valueToTransfer = 100;

      //@audit-info => a retail EU investor transfers to a qualified (non-retail) EU investor
      const dsTokenFromInvestor = await dsToken.connect(investor);
      await dsTokenFromInvestor.transfer(investor2, valueToTransfer);
      expect(await complianceService.getEURetailInvestorsCount(INVESTORS.Country.FRANCE)).equal(1);

      //@audit-info => Set investor2 as retail investor - non-qualified!
      await registryService.setAttribute(INVESTORS.INVESTOR_ID.INVESTOR_ID_2, 4, 0, 0, 'abcde');
      const dsTokenFromInvestor2 = await dsToken.connect(investor2);
      //@audit-info => The old qualified investor, currently retail, transfers all its balance to another retail EU investor
      await dsTokenFromInvestor2.transfer(investor, valueToTransfer);
      expect(await complianceService.getEURetailInvestorsCount(INVESTORS.Country.FRANCE)).equal(0);

      //@audit-info => investor1 tries to transfer all of its balance to an investor on another country and reverts bcs of underflow on euRetailInvestorsCount
      await expect(dsTokenFromInvestor.transfer(usInvestor, 500)).to.be.reverted;
    });