forked from OpenZeppelin/openzeppelin-contracts
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simplify implementation using similar interface as PullPayment contract
- Loading branch information
Showing
6 changed files
with
62 additions
and
247 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,148 +1,65 @@ | ||
pragma solidity ^0.4.15; | ||
pragma solidity ^0.4.11; | ||
|
||
import '../ReentrancyGuard.sol'; | ||
import '../math/SafeMath.sol'; | ||
|
||
/** | ||
* @title SplitPayment | ||
* @dev Base contract supporting the distribution of funds send to this contract to multiple payees. | ||
* @dev Base contract that supports multiple payees claiming funds sent to this contract | ||
* according to the proportion they own. | ||
*/ | ||
contract SplitPayment is ReentrancyGuard { | ||
contract SplitPayment { | ||
using SafeMath for uint256; | ||
|
||
struct Payee { | ||
address addr; | ||
uint256 shares; | ||
} | ||
|
||
uint256 public totalShares = 0; | ||
uint256 public maxPayees = 0; | ||
uint256 public totalReleased = 0; | ||
|
||
mapping(address => uint256) payeeIndex; | ||
Payee[] payees; | ||
mapping(address => uint256) public shares; | ||
mapping(address => uint256) public released; | ||
address[] public payees; | ||
|
||
/** | ||
* @dev Constructor | ||
* @param _maxPayees Total number of payees allowed. Zero for no limit. | ||
*/ | ||
function SplitPayment(uint256 _maxPayees) { | ||
maxPayees = _maxPayees; | ||
} | ||
|
||
/** | ||
* @dev Modifier that throws if you want to distribute funds and you are not a payee. | ||
*/ | ||
modifier canDistribute() { | ||
require(isPayee(msg.sender)); | ||
_; | ||
} | ||
function SplitPayment(address[] _payees, uint256[] _shares) { | ||
require(_payees.length == _shares.length); | ||
|
||
/** | ||
* @dev Modifier that throws if not allowed to update payees. | ||
* Override from child contract with your own requirements for access control. | ||
*/ | ||
modifier canUpdate() { | ||
_; | ||
for (uint256 i = 0; i < _payees.length; i++) { | ||
addPayee(_payees[i], _shares[i]); | ||
} | ||
} | ||
|
||
/** | ||
* @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) public canUpdate { | ||
function addPayee(address _payee, uint256 _shares) internal { | ||
require(_payee != address(0)); | ||
require(_shares > 0); | ||
require(!isPayee(_payee)); | ||
require(maxPayees == 0 || payees.length.add(1) <= maxPayees); | ||
require(shares[_payee] == 0); | ||
|
||
payees.push(Payee(_payee, _shares)); | ||
payeeIndex[_payee] = payees.length; | ||
payees.push(_payee); | ||
shares[_payee] = _shares; | ||
totalShares = totalShares.add(_shares); | ||
} | ||
|
||
/** | ||
* @dev Add multiple payees to the contract. | ||
* @param _payees An array of addresses of payees to add. | ||
* @param _shares An array of the shares corresponding to each payee in the _payees array. | ||
*/ | ||
function addPayeeMany(address[] _payees, uint256[] _shares) public canUpdate { | ||
require(_payees.length == _shares.length); | ||
require(maxPayees == 0 || payees.length.add(_payees.length) <= maxPayees); | ||
|
||
for (uint256 i = 0; i < _payees.length; i++) { | ||
addPayee(_payees[i], _shares[i]); | ||
} | ||
} | ||
|
||
/** | ||
* @dev Return true if the payee is in the contract. | ||
* @param _payee The address of the payee to check. | ||
*/ | ||
function isPayee(address _payee) public constant returns (bool) { | ||
return payeeIndex[_payee] > 0; | ||
} | ||
|
||
/** | ||
* @dev Return the number of payees in the contract. | ||
* @dev Claim your share of the balance. | ||
*/ | ||
function getPayeeCount() public constant returns (uint256) { | ||
return payees.length; | ||
} | ||
function claim() public { | ||
address payee = msg.sender; | ||
|
||
/** | ||
* @dev Return the address of the payee and its shares. | ||
* Throws if the payee is not in the contract. | ||
* @param _payee The address of the payee to get. | ||
*/ | ||
function getPayee(address _payee) public constant returns (address, uint256) { | ||
require(isPayee(_payee)); | ||
require(shares[payee] > 0); | ||
|
||
return getPayeeAtIndex(payeeIndex[_payee] - 1); | ||
} | ||
uint256 totalReceived = this.balance.add(totalReleased); | ||
uint256 payment = totalReceived.mul(shares[payee]).div(totalShares).sub(released[payee]); | ||
|
||
/** | ||
* @dev Return the address of the payee and its shares by index. | ||
* Allows iterating through the payee list from a client by knowing the payee count. | ||
* @param _idx The index of the payee in the internal list. | ||
*/ | ||
function getPayeeAtIndex(uint256 _idx) public constant returns (address, uint256) { | ||
require(_idx < payees.length); | ||
require(payment != 0); | ||
require(this.balance >= payment); | ||
|
||
return (payees[_idx].addr, payees[_idx].shares); | ||
} | ||
released[payee] = released[payee].add(payment); | ||
totalReleased = totalReleased.add(payment); | ||
|
||
/** | ||
* @dev Perform the payment to a payee. | ||
* This can be overriden to provide different transfer mechanisms. | ||
* @param _payee The address of the payee to be paid. | ||
* @param _amount The amount for the payment. | ||
*/ | ||
function pay(address _payee, uint256 _amount) internal { | ||
_payee.transfer(_amount); | ||
} | ||
|
||
/** | ||
* @dev Return the total amount of funds available for distribution. | ||
*/ | ||
function toDistribute() internal returns (uint256) { | ||
return this.balance; | ||
} | ||
|
||
/** | ||
* @dev Send payments to the registered payees according to their shares and the total | ||
* amount of funds to distribute. | ||
*/ | ||
function distributeFunds() public canDistribute nonReentrant { | ||
uint256 amountDistribute = toDistribute(); | ||
assert(amountDistribute > 0); | ||
|
||
Payee memory payee; | ||
for (uint256 i = 0; i < payees.length; i++) { | ||
payee = payees[i]; | ||
|
||
uint256 amount = amountDistribute.mul(payee.shares).div(totalShares); | ||
pay(payee.addr, amount); | ||
} | ||
payee.transfer(payment); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
pragma solidity ^0.4.15; | ||
pragma solidity ^0.4.11; | ||
|
||
import '../../contracts/payment/SplitPayment.sol'; | ||
|
||
// mock class using SplitPayment | ||
contract SplitPaymentMock is SplitPayment { | ||
function SplitPaymentMock() SplitPayment(0) payable { } | ||
function SplitPaymentMock(address[] _payees, uint256[] _shares) | ||
SplitPayment(_payees, _shares) payable {} | ||
function () payable {} | ||
} |
This file was deleted.
Oops, something went wrong.