Browse Source

Improve PullPayment docs (#1965)

* Improve PullPayment docs

* Reword escrow note

* Update contracts/payment/PullPayment.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>
Nicolás Venturo 6 years ago
parent
commit
9e19d90cd9
1 changed files with 23 additions and 6 deletions
  1. 23 6
      contracts/payment/PullPayment.sol

+ 23 - 6
contracts/payment/PullPayment.sol

@@ -3,9 +3,18 @@ pragma solidity ^0.5.0;
 import "./escrow/Escrow.sol";
 
 /**
- * @title PullPayment
- * @dev Base contract supporting async send for pull payments. Inherit from this
- * contract and use {_asyncTransfer} instead of send or transfer.
+ * @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;
@@ -15,15 +24,20 @@ contract PullPayment {
     }
 
     /**
-     * @dev Withdraw accumulated balance.
-     * @param payee Whose balance will be withdrawn.
+     * @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 credit owed to an address.
+     * @dev Returns the payments owed to an address.
      * @param dest The creditor's address.
      */
     function payments(address dest) public view returns (uint256) {
@@ -34,6 +48,9 @@ contract PullPayment {
      * @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);