/**
* @title PaymentSplitter
* This contract allows the splitting of Filecoin payments among a group of accounts. The sender does not need to be aware
* that the FIL will be split in this way, since it is handled transparently by the contract.
*
* The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
* account to a number of shares. Of all the FIL that this contract receives, each account will then be able to claim
* an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the
* time of contract deployment and can't be updated thereafter.
*
* `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
* accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
* function.
*
*/
contract PaymentSplitter {
// Emitted events
event PayeeAdded(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount);
event PaymentReceived(address from, uint256 amount);
// Running logs of the total shares to dispense and the current amount released.
uint256 private _totalShares;
uint256 private _totalReleased;
// Maps of payees to shares owed and shares already released.
mapping(address => uint256) private _shares;
mapping(address => uint256) private _released;
address[] private _payees;
/**
* @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
* the matching position in the `shares` array. Instantiates _shares, _payees, _totalShares.
*
* All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
* duplicates in `payees`.
*/
constructor(address[] memory payees, uint256[] memory shares_) payable {...}
/**
* @dev The FIL received will be logged with {PaymentReceived} events. Note that these events are not fully
* reliable: it's possible for a contract to receive FIL without triggering this function. This only affects the
* reliability of the events, and not the actual splitting of FIL.
*/
receive() external payable virtual {...}
/**
* @dev Getter for the total shares held by payees (_totalShares).
*/
function totalShares() public view returns (uint256) {...}
/**
* @dev Getter for the total amount of FIL already released (_totalReleased).
*/
function totalReleased() public view returns (uint256) {...}
/**
* @dev Getter for the amount of shares held by an account.
*/
function shares(address account) public view returns (uint256) {...}
/**
* @dev Getter for the amount of FIL already released to a payee.
*/
function released(address account) public view returns (uint256) {...}
/**
* @dev Getter for the address of the payee number `index`.
*/
function payee(uint256 index) public view returns (address) {...}
/**
* @dev Getter for the amount of payee's releasable FIL.
*/
function releasable(address account) public view returns (uint256) {...}
/**
* @dev Triggers a transfer to `account` of the amount of FIL they are owed, according to their percentage of the
* total shares and their previous withdrawals.
*/
function release(address payable account) public virtual {...}
/**
* @dev internal logic for computing the pending payment of an `account` given the token historical balances and
* already released amounts.
*/
function _pendingPayment(
address account,
uint256 totalReceived,
uint256 alreadyReleased
) private view returns (uint256) {...}
/**
* @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_) private {...}