Files
openzeppelin-contracts/contracts/payment/PullPayment.sol
Nicolás Venturo 5dfe7215a9 Migrate Contracts to Solidity v0.6 (#2080)
* Initial migration to Solidity 0.6.x - v3.0 first steps (#2063)

* Initial migration, missing GSN, 721, 777 and Crowdsales.

* Add _beforeTokenOperation and _afterTokenOperation.

* Add documentation for hooks.

* Add hooks doc

* Add missing drafts

* Add back ERC721 with hooks

* Bring back ERC777

* Notes on hooks

* Bring back GSN

* Make functions virtual

* Make GSN overrides explicit

* Fix ERC20Pausable tests

* Remove virtual from some view functions

* Update linter

* Delete examples

* Remove unnecessary virtual

* Remove roles from Pausable

* Remove roles

* Remove users of roles

* Adapt ERC20 tests

* Fix ERC721 tests

* Add all ERC721 hooks

* Add ERC777 hooks

* Fix remaining tests

* Bump compiler version

* Move 721BurnableMock into mocks directory

* Remove _before hooks

* Fix tests

* Upgrade linter

* Put modifiers last

* Remove _beforeTokenApproval and _beforeOperatorApproval hooks
2020-02-14 11:12:32 -03:00

82 lines
3.1 KiB
Solidity

pragma solidity ^0.6.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.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*
* 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.
*
* 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}.
*
* NOTE: This function has been deprecated, use {withdrawPaymentsWithGas}
* instead. Calling contracts with fixed gas limits is an anti-pattern and
* may break contract interactions in network upgrades (hardforks).
* https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more.]
*
* @param payee Whose payments will be withdrawn.
*/
function withdrawPayments(address payable payee) public virtual {
_escrow.withdraw(payee);
}
/**
* @dev Same as {withdrawPayments}, but forwarding all gas to the recipient.
*
* WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
* Make sure you trust the recipient, or are either following the
* checks-effects-interactions pattern or using {ReentrancyGuard}.
*
* _Available since v2.4.0._
*/
function withdrawPaymentsWithGas(address payable payee) external virtual {
_escrow.withdrawWithGas(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.
* Funds sent in this way are stored in an intermediate {Escrow} contract, so
* there is no danger of them being spent before withdrawal.
*
* @param dest The destination address of the funds.
* @param amount The amount to transfer.
*/
function _asyncTransfer(address dest, uint256 amount) internal virtual {
_escrow.deposit.value(amount)(dest);
}
}