```\nfunction _distributeERC20(\n  address split,\n  ERC20 token,\n  address[] memory accounts,\n  uint32[] memory percentAllocations,\n  uint32 distributorFee,\n  address distributorAddress\n) internal {\n  uint256 amountToSplit;\n  uint256 mainBalance = erc20Balances[token][split];\n  uint256 proxyBalance = token.balanceOf(split);\n  unchecked {\n    // if mainBalance &/ proxyBalance are positive, leave 1 for gas efficiency\n    // underflow should be impossible\n    if (proxyBalance > 0) proxyBalance -= 1;\n    // underflow should be impossible\n    if (mainBalance > 0) {\n      mainBalance -= 1;\n    }\n    // overflow should be impossible\n    amountToSplit = mainBalance + proxyBalance;\n  }\n  if (mainBalance > 0) erc20Balances[token][split] = 1;\n  // emit event with gross amountToSplit (before deducting distributorFee)\n  emit DistributeERC20(split, token, amountToSplit, distributorAddress);\n  if (distributorFee != 0) {\n    // given `amountToSplit`, calculate keeper fee\n    uint256 distributorFeeAmount = _scaleAmountByPercentage(\n      amountToSplit,\n      distributorFee\n    );\n    // overflow should be impossible with validated distributorFee\n    unchecked {\n      // credit keeper with fee\n      erc20Balances[token][\n        distributorAddress != address(0) ? distributorAddress : msg.sender\n      ] += distributorFeeAmount;\n      // given keeper fee, calculate how much to distribute to split recipients\n      amountToSplit -= distributorFeeAmount;\n    }\n  }\n  // distribute remaining balance\n  // overflows should be impossible in for-loop with validated allocations\n  unchecked {\n    // cache accounts length to save gas\n    uint256 accountsLength = accounts.length;\n    for (uint256 i = 0; i < accountsLength; ++i) {\n      erc20Balances[token][accounts[i]] += _scaleAmountByPercentage(\n        amountToSplit,\n        percentAllocations[i]\n      );\n    }\n  }\n  // split proxy should be guaranteed to exist at this address after validating splitHash\n  // (attacker can't deploy own contract to address with high ERC20 balance & empty\n  // sendERC20ToMain to drain ERC20 from SplitMain)\n  // doesn't support rebasing or fee-on-transfer tokens\n  // flush extra proxy ERC20 balance to SplitMain\n  if (proxyBalance > 0)\n    SplitWallet(split).sendERC20ToMain(token, proxyBalance);\n}\n```\n