PaymentSplitter
Automatically splits incoming native payments among recipients by configurable shares.
PaymentSplitter.sol
// SPDX-License-Identifier: MITpragma solidity ^0.8.20; contract PaymentSplitter { address[] public payees; uint256 public totalShares; uint256 public totalReleased; mapping(address => uint256) public shares; mapping(address => uint256) public released; event PaymentReceived(address from, uint256 amount); event PaymentReleased(address to, uint256 amount); constructor(address[] memory payees_, uint256[] memory shares_) { require(payees_.length == shares_.length && payees_.length > 0, "BAD_INPUT"); for (uint256 i = 0; i < payees_.length; i++) { address account = payees_[i]; uint256 sh = shares_[i]; require(account != address(0) && sh > 0 && shares[account] == 0, "BAD_PAYEE"); payees.push(account); shares[account] = sh; totalShares += sh; } } receive() external payable { emit PaymentReceived(msg.sender, msg.value); } function releasable(address account) public view returns (uint256) { uint256 totalReceived = address(this).balance + totalReleased; return (totalReceived * shares[account]) / totalShares - released[account]; } function release(address account) external { require(shares[account] > 0, "NO_SHARES"); uint256 payment = releasable(account); require(payment > 0, "NOT_DUE"); released[account] += payment; totalReleased += payment; (bool ok, ) = payable(account).call{value: payment}(""); require(ok, "TRANSFER_FAILED"); emit PaymentReleased(account, payment); }}