DevStation / LaunchKit / Templates / PaymentSplitter

PaymentSplitter

Automatically splits incoming native payments among recipients by configurable shares.

Deploy This Template
PaymentSplitter.sol
solidity
1// SPDX-License-Identifier: MIT
2pragma solidity ^0.8.20;
3 
4contract PaymentSplitter {
5 address[] public payees;
6 uint256 public totalShares;
7 uint256 public totalReleased;
8 mapping(address => uint256) public shares;
9 mapping(address => uint256) public released;
10 
11 event PaymentReceived(address from, uint256 amount);
12 event PaymentReleased(address to, uint256 amount);
13 
14 constructor(address[] memory payees_, uint256[] memory shares_) {
15 require(payees_.length == shares_.length && payees_.length > 0, "BAD_INPUT");
16 for (uint256 i = 0; i < payees_.length; i++) {
17 address account = payees_[i];
18 uint256 sh = shares_[i];
19 require(account != address(0) && sh > 0 && shares[account] == 0, "BAD_PAYEE");
20 payees.push(account);
21 shares[account] = sh;
22 totalShares += sh;
23 }
24 }
25 
26 receive() external payable {
27 emit PaymentReceived(msg.sender, msg.value);
28 }
29 
30 function releasable(address account) public view returns (uint256) {
31 uint256 totalReceived = address(this).balance + totalReleased;
32 return (totalReceived * shares[account]) / totalShares - released[account];
33 }
34 
35 function release(address account) external {
36 require(shares[account] > 0, "NO_SHARES");
37 uint256 payment = releasable(account);
38 require(payment > 0, "NOT_DUE");
39 released[account] += payment;
40 totalReleased += payment;
41 (bool ok, ) = payable(account).call{value: payment}("");
42 require(ok, "TRANSFER_FAILED");
43 emit PaymentReleased(account, payment);
44 }
45}
DevStation
Loading console…