123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- pragma solidity ^0.4.24;
- import "../math/SafeMath.sol";
- /**
- * @title SplitPayment
- * @dev This contract can be used when payments need to be received by a group
- * of people and split proportionately to some number of shares they own.
- */
- contract SplitPayment {
- using SafeMath for uint256;
- uint256 private totalShares_ = 0;
- uint256 private totalReleased_ = 0;
- mapping(address => uint256) private shares_;
- mapping(address => uint256) private released_;
- address[] private payees_;
- /**
- * @dev Constructor
- */
- constructor(address[] _payees, uint256[] _shares) public payable {
- require(_payees.length == _shares.length);
- require(_payees.length > 0);
- for (uint256 i = 0; i < _payees.length; i++) {
- _addPayee(_payees[i], _shares[i]);
- }
- }
- /**
- * @dev payable fallback
- */
- function () external payable {}
- /**
- * @return the total shares of the contract.
- */
- function totalShares() public view returns(uint256) {
- return totalShares_;
- }
- /**
- * @return the total amount already released.
- */
- function totalReleased() public view returns(uint256) {
- return totalReleased_;
- }
- /**
- * @return the shares of an account.
- */
- function shares(address _account) public view returns(uint256) {
- return shares_[_account];
- }
- /**
- * @return the amount already released to an account.
- */
- function released(address _account) public view returns(uint256) {
- return released_[_account];
- }
- /**
- * @return the address of a payee.
- */
- function payee(uint256 index) public view returns(address) {
- return payees_[index];
- }
- /**
- * @dev Release one of the payee's proportional payment.
- * @param _payee Whose payments will be released.
- */
- function release(address _payee) public {
- require(shares_[_payee] > 0);
- uint256 totalReceived = address(this).balance.add(totalReleased_);
- uint256 payment = totalReceived.mul(
- shares_[_payee]).div(
- totalShares_).sub(
- released_[_payee]
- );
- require(payment != 0);
- assert(address(this).balance >= payment);
- released_[_payee] = released_[_payee].add(payment);
- totalReleased_ = totalReleased_.add(payment);
- _payee.transfer(payment);
- }
- /**
- * @dev Add a new payee to the contract.
- * @param _payee The address of the payee to add.
- * @param _shares The number of shares owned by the payee.
- */
- function _addPayee(address _payee, uint256 _shares) internal {
- require(_payee != address(0));
- require(_shares > 0);
- require(shares_[_payee] == 0);
- payees_.push(_payee);
- shares_[_payee] = _shares;
- totalShares_ = totalShares_.add(_shares);
- }
- }
|