PaymentSplitter.sol 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.8.0-rc.0) (finance/PaymentSplitter.sol)
  3. pragma solidity ^0.8.0;
  4. import "../token/ERC20/utils/SafeERC20.sol";
  5. import "../utils/Address.sol";
  6. import "../utils/Context.sol";
  7. /**
  8. * @title PaymentSplitter
  9. * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
  10. * that the Ether will be split in this way, since it is handled transparently by the contract.
  11. *
  12. * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
  13. * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
  14. * an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the
  15. * time of contract deployment and can't be updated thereafter.
  16. *
  17. * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
  18. * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
  19. * function.
  20. *
  21. * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
  22. * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
  23. * to run tests before sending real value to this contract.
  24. */
  25. contract PaymentSplitter is Context {
  26. event PayeeAdded(address account, uint256 shares);
  27. event PaymentReleased(address to, uint256 amount);
  28. event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
  29. event PaymentReceived(address from, uint256 amount);
  30. uint256 private _totalShares;
  31. uint256 private _totalReleased;
  32. mapping(address => uint256) private _shares;
  33. mapping(address => uint256) private _released;
  34. address[] private _payees;
  35. mapping(IERC20 => uint256) private _erc20TotalReleased;
  36. mapping(IERC20 => mapping(address => uint256)) private _erc20Released;
  37. /**
  38. * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
  39. * the matching position in the `shares` array.
  40. *
  41. * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
  42. * duplicates in `payees`.
  43. */
  44. constructor(address[] memory payees, uint256[] memory shares_) payable {
  45. require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
  46. require(payees.length > 0, "PaymentSplitter: no payees");
  47. for (uint256 i = 0; i < payees.length; i++) {
  48. _addPayee(payees[i], shares_[i]);
  49. }
  50. }
  51. /**
  52. * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
  53. * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
  54. * reliability of the events, and not the actual splitting of Ether.
  55. *
  56. * To learn more about this see the Solidity documentation for
  57. * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
  58. * functions].
  59. */
  60. receive() external payable virtual {
  61. emit PaymentReceived(_msgSender(), msg.value);
  62. }
  63. /**
  64. * @dev Getter for the total shares held by payees.
  65. */
  66. function totalShares() public view returns (uint256) {
  67. return _totalShares;
  68. }
  69. /**
  70. * @dev Getter for the total amount of Ether already released.
  71. */
  72. function totalReleased() public view returns (uint256) {
  73. return _totalReleased;
  74. }
  75. /**
  76. * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
  77. * contract.
  78. */
  79. function totalReleased(IERC20 token) public view returns (uint256) {
  80. return _erc20TotalReleased[token];
  81. }
  82. /**
  83. * @dev Getter for the amount of shares held by an account.
  84. */
  85. function shares(address account) public view returns (uint256) {
  86. return _shares[account];
  87. }
  88. /**
  89. * @dev Getter for the amount of Ether already released to a payee.
  90. */
  91. function released(address account) public view returns (uint256) {
  92. return _released[account];
  93. }
  94. /**
  95. * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
  96. * IERC20 contract.
  97. */
  98. function released(IERC20 token, address account) public view returns (uint256) {
  99. return _erc20Released[token][account];
  100. }
  101. /**
  102. * @dev Getter for the address of the payee number `index`.
  103. */
  104. function payee(uint256 index) public view returns (address) {
  105. return _payees[index];
  106. }
  107. /**
  108. * @dev Getter for the amount of payee's releasable Ether.
  109. */
  110. function releasable(address account) public view returns (uint256) {
  111. uint256 totalReceived = address(this).balance + totalReleased();
  112. return _pendingPayment(account, totalReceived, released(account));
  113. }
  114. /**
  115. * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an
  116. * IERC20 contract.
  117. */
  118. function releasable(IERC20 token, address account) public view returns (uint256) {
  119. uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
  120. return _pendingPayment(account, totalReceived, released(token, account));
  121. }
  122. /**
  123. * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
  124. * total shares and their previous withdrawals.
  125. */
  126. function release(address payable account) public virtual {
  127. require(_shares[account] > 0, "PaymentSplitter: account has no shares");
  128. uint256 payment = releasable(account);
  129. require(payment != 0, "PaymentSplitter: account is not due payment");
  130. // _totalReleased is the sum of all values in _released.
  131. // If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow.
  132. _totalReleased += payment;
  133. unchecked {
  134. _released[account] += payment;
  135. }
  136. Address.sendValue(account, payment);
  137. emit PaymentReleased(account, payment);
  138. }
  139. /**
  140. * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
  141. * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
  142. * contract.
  143. */
  144. function release(IERC20 token, address account) public virtual {
  145. require(_shares[account] > 0, "PaymentSplitter: account has no shares");
  146. uint256 payment = releasable(token, account);
  147. require(payment != 0, "PaymentSplitter: account is not due payment");
  148. // _erc20TotalReleased[token] is the sum of all values in _erc20Released[token].
  149. // If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment"
  150. // cannot overflow.
  151. _erc20TotalReleased[token] += payment;
  152. unchecked {
  153. _erc20Released[token][account] += payment;
  154. }
  155. SafeERC20.safeTransfer(token, account, payment);
  156. emit ERC20PaymentReleased(token, account, payment);
  157. }
  158. /**
  159. * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
  160. * already released amounts.
  161. */
  162. function _pendingPayment(
  163. address account,
  164. uint256 totalReceived,
  165. uint256 alreadyReleased
  166. ) private view returns (uint256) {
  167. return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
  168. }
  169. /**
  170. * @dev Add a new payee to the contract.
  171. * @param account The address of the payee to add.
  172. * @param shares_ The number of shares owned by the payee.
  173. */
  174. function _addPayee(address account, uint256 shares_) private {
  175. require(account != address(0), "PaymentSplitter: account is the zero address");
  176. require(shares_ > 0, "PaymentSplitter: shares are 0");
  177. require(_shares[account] == 0, "PaymentSplitter: account already has shares");
  178. _payees.push(account);
  179. _shares[account] = shares_;
  180. _totalShares = _totalShares + shares_;
  181. emit PayeeAdded(account, shares_);
  182. }
  183. }