pragma solidity ^0.5.0; import "./escrow/Escrow.sol"; /** * @dev Simple implementation of a * https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls[pull-payment] * strategy, where the paying contract doesn't interact directly with the * receiver account, which must withdraw its payments itself. * * Pull-payments are often considered the best practice when it comes to sending * Ether, security-wise. It prevents recipients from blocking execution, and * eliminates reentrancy concerns. * * To use, derive from the `PullPayment` contract, and use {_asyncTransfer} * instead of Solidity's `transfer` function. Payees can query their due * payments with {payments}, and retrieve them with {withdrawPayments}. */ contract PullPayment { Escrow private _escrow; constructor () internal { _escrow = new Escrow(); } /** * @dev Withdraw accumulated payments. * @param payee Whose payments will be withdrawn. * * Note that _any_ account can call this function, not just the `payee`. * This means that contracts unaware of the `PullPayment` protocol can still * receive funds this way, by having a separate account call * {withdrawPayments}. */ function withdrawPayments(address payable payee) public { _escrow.withdraw(payee); } /** * @dev Returns the payments owed to an address. * @param dest The creditor's address. */ function payments(address dest) public view returns (uint256) { return _escrow.depositsOf(dest); } /** * @dev Called by the payer to store the sent amount as credit to be pulled. * @param dest The destination address of the funds. * @param amount The amount to transfer. * * Funds sent in this way are stored in an intermediate {Escrow} contract, so * there is no danger of them being spent before withdrawal. */ function _asyncTransfer(address dest, uint256 amount) internal { _escrow.deposit.value(amount)(dest); } }