```\nfunction _distributeETH(\n  address split,\n  address[] memory accounts,\n  uint32[] memory percentAllocations,\n  uint32 distributorFee,\n  address distributorAddress\n) internal {\n  uint256 mainBalance = ethBalances[split];\n  uint256 proxyBalance = split.balance;\n  // if mainBalance is positive, leave 1 in SplitMain for gas efficiency\n  uint256 amountToSplit;\n  unchecked {\n    // underflow should be impossible\n    if (mainBalance > 0) mainBalance -= 1;\n    // overflow should be impossible\n    amountToSplit = mainBalance + proxyBalance;\n  }\n  if (mainBalance > 0) ethBalances[split] = 1;\n  // emit event with gross amountToSplit (before deducting distributorFee)\n  emit DistributeETH(split, amountToSplit, distributorAddress);\n  if (distributorFee != 0) {\n    // given `amountToSplit`, calculate keeper fee\n    uint256 distributorFeeAmount = _scaleAmountByPercentage(\n      amountToSplit,\n      distributorFee\n    );\n    unchecked {\n      // credit keeper with fee\n      // overflow should be impossible with validated distributorFee\n      ethBalances[\n        distributorAddress != address(0) ? distributorAddress : msg.sender\n      ] += distributorFeeAmount;\n      // given keeper fee, calculate how much to distribute to split recipients\n      // underflow should be impossible with validated distributorFee\n      amountToSplit -= distributorFeeAmount;\n    }\n  }\n  unchecked {\n    // distribute remaining balance\n    // overflow should be impossible in for-loop index\n    // cache accounts length to save gas\n    uint256 accountsLength = accounts.length;\n    for (uint256 i = 0; i < accountsLength; ++i) {\n      // overflow should be impossible with validated allocations\n      ethBalances[accounts[i]] += _scaleAmountByPercentage(\n        amountToSplit,\n        percentAllocations[i]\n      );\n    }\n  }\n  // flush proxy ETH balance to SplitMain\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 balance & empty sendETHToMain\n  // to drain ETH from SplitMain)\n  // could technically check if (change in proxy balance == change in SplitMain balance)\n  // before/after external call, but seems like extra gas for no practical benefit\n  if (proxyBalance > 0) SplitWallet(split).sendETHToMain(proxyBalance);\n}\n```\n