PaymentSplitter.sol 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. pragma solidity ^0.4.24;
  2. import "../math/SafeMath.sol";
  3. /**
  4. * @title PaymentSplitter
  5. * @dev This contract can be used when payments need to be received by a group
  6. * of people and split proportionately to some number of shares they own.
  7. */
  8. contract PaymentSplitter {
  9. using SafeMath for uint256;
  10. event PayeeAdded(address account, uint256 shares);
  11. event PaymentReleased(address to, uint256 amount);
  12. event PaymentReceived(address from, uint256 amount);
  13. uint256 private _totalShares;
  14. uint256 private _totalReleased;
  15. mapping(address => uint256) private _shares;
  16. mapping(address => uint256) private _released;
  17. address[] private _payees;
  18. /**
  19. * @dev Constructor
  20. */
  21. constructor (address[] payees, uint256[] shares) public payable {
  22. require(payees.length == shares.length);
  23. require(payees.length > 0);
  24. for (uint256 i = 0; i < payees.length; i++) {
  25. _addPayee(payees[i], shares[i]);
  26. }
  27. }
  28. /**
  29. * @dev payable fallback
  30. */
  31. function () external payable {
  32. emit PaymentReceived(msg.sender, msg.value);
  33. }
  34. /**
  35. * @return the total shares of the contract.
  36. */
  37. function totalShares() public view returns (uint256) {
  38. return _totalShares;
  39. }
  40. /**
  41. * @return the total amount already released.
  42. */
  43. function totalReleased() public view returns (uint256) {
  44. return _totalReleased;
  45. }
  46. /**
  47. * @return the shares of an account.
  48. */
  49. function shares(address account) public view returns (uint256) {
  50. return _shares[account];
  51. }
  52. /**
  53. * @return the amount already released to an account.
  54. */
  55. function released(address account) public view returns (uint256) {
  56. return _released[account];
  57. }
  58. /**
  59. * @return the address of a payee.
  60. */
  61. function payee(uint256 index) public view returns (address) {
  62. return _payees[index];
  63. }
  64. /**
  65. * @dev Release one of the payee's proportional payment.
  66. * @param account Whose payments will be released.
  67. */
  68. function release(address account) public {
  69. require(_shares[account] > 0);
  70. uint256 totalReceived = address(this).balance.add(_totalReleased);
  71. uint256 payment = totalReceived.mul(_shares[account]).div(_totalShares).sub(_released[account]);
  72. require(payment != 0);
  73. _released[account] = _released[account].add(payment);
  74. _totalReleased = _totalReleased.add(payment);
  75. account.transfer(payment);
  76. emit PaymentReleased(account, payment);
  77. }
  78. /**
  79. * @dev Add a new payee to the contract.
  80. * @param account The address of the payee to add.
  81. * @param shares_ The number of shares owned by the payee.
  82. */
  83. function _addPayee(address account, uint256 shares_) private {
  84. require(account != address(0));
  85. require(shares_ > 0);
  86. require(_shares[account] == 0);
  87. _payees.push(account);
  88. _shares[account] = shares_;
  89. _totalShares = _totalShares.add(shares_);
  90. emit PayeeAdded(account, shares_);
  91. }
  92. }