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;
- uint256 private _totalReleased;
- 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);
- _totalShares = 0;
- _totalReleased = 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 account Whose payments will be released.
- */
- function release(address account) public {
- require(_shares[account] > 0);
- uint256 totalReceived = address(this).balance.add(_totalReleased);
- uint256 payment = totalReceived.mul(
- _shares[account]).div(
- _totalShares).sub(
- _released[account]
- );
- require(payment != 0);
- _released[account] = _released[account].add(payment);
- _totalReleased = _totalReleased.add(payment);
- account.transfer(payment);
- }
- /**
- * @dev Add a new payee to the contract.
- * @param account The address of the payee to add.
- * @param shares_ The number of shares owned by the payee.
- */
- function _addPayee(address account, uint256 shares_) internal {
- require(account != address(0));
- require(shares_ > 0);
- require(_shares[account] == 0);
- _payees.push(account);
- _shares[account] = shares_;
- _totalShares = _totalShares.add(shares_);
- }
- }
|