Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward all gas on PullPayment withdrawal #1976

Merged
merged 9 commits into from
Oct 28, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@
* `Address.toPayable`: added a helper to convert between address types without having to resort to low-level casting. ([#1773](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1773))
* Facilities to make metatransaction-enabled contracts through the Gas Station Network. ([#1844](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1844))
* `Address.sendValue`: added a replacement to Solidity's `transfer`, removing the fixed gas stipend. ([#1962](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1962))
* `PullPayment.withdrawPaymentsWithGas(address payable payee)`: replacement for the deprecated version (see below), forwarding all available gas. ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
* `Escrow.withdrawWithGas(address payable payee)`: replacement for the deprecated version (see below), forwarding all available gas. ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
nventuro marked this conversation as resolved.
Show resolved Hide resolved

### Improvements:
* `Address.isContract`: switched from `extcodesize` to `extcodehash` for less gas usage. ([#1802](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1802))
* `SafeMath`: added custom error messages support for `sub`, `div` and `mod` functions. `ERC20` and `ERC777` updated to throw custom errors on subtraction overflows. ([#1828](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1828))

### Deprecations:
* `PullPayment.withdrawPayments(address payable payee)`: due to the payee being forwarded a fixed gas allowance (2300 gas). ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))
* `Escrow.withdraw(address payable payee)`: due to the payee being forwarded a fixed gas allowance (2300 gas). ([#1976](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1976))

### Breaking changes in drafts:
* `SignatureBouncer` has been removed from the library, both to avoid confusions with the GSN Bouncers and `GSNBouncerSignature` and because the API was not very clear. ([#1879](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1879))

Expand Down
20 changes: 20 additions & 0 deletions contracts/payment/PullPayment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,31 @@ contract PullPayment {
* 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}
frangio marked this conversation as resolved.
Show resolved Hide resolved
* instead. Calling contracts with fixed-gas limits is an anti-pattern and
nventuro marked this conversation as resolved.
Show resolved Hide resolved
* may break contract interactions in network upgrades (hardforks).
* https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more.]
*/
function withdrawPayments(address payable payee) public {
_escrow.withdraw(payee);
}

/**
* @dev Same as {withdrawPayments}, but forwarding all gas to the recipient.
*
* Calling contracts with fixed-gas limits is an anti-pattern and may break
nventuro marked this conversation as resolved.
Show resolved Hide resolved
* contract interactions in network upgrades (hardforks).
* https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more here.]
*
* 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}.
*/
function withdrawPaymentsWithGas(address payable payee) public {
_escrow.withdrawWithGas(payee);
}

/**
* @dev Returns the payments owed to an address.
* @param dest The creditor's address.
Expand Down
28 changes: 27 additions & 1 deletion contracts/payment/escrow/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pragma solidity ^0.5.0;

import "../../math/SafeMath.sol";
import "../../ownership/Secondary.sol";
import "../../utils/Address.sol";

/**
* @title Escrow
Expand All @@ -18,6 +19,7 @@ import "../../ownership/Secondary.sol";
*/
contract Escrow is Secondary {
using SafeMath for uint256;
using Address for address payable;

event Deposited(address indexed payee, uint256 weiAmount);
event Withdrawn(address indexed payee, uint256 weiAmount);
Expand All @@ -40,8 +42,15 @@ contract Escrow is Secondary {
}

/**
* @dev Withdraw accumulated balance for a payee.
* @dev Withdraw accumulated balance for a payee, forwarding 2300 gas (a
* Solidity `transfer`).
*
* @param payee The address whose funds will be withdrawn and transferred to.
*
* NOTE: This function has been deprecated, use {withdrawWithGas} 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.]
*/
function withdraw(address payable payee) public onlyPrimary {
uint256 payment = _deposits[payee];
Expand All @@ -52,4 +61,21 @@ contract Escrow is Secondary {

emit Withdrawn(payee, payment);
}

/**
* @dev Same as {withdraw}, 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}.
*/
function withdrawWithGas(address payable payee) public onlyPrimary {
uint256 payment = _deposits[payee];

_deposits[payee] = 0;

payee.sendValue(payment);

emit Withdrawn(payee, payment);
}
}
12 changes: 12 additions & 0 deletions test/payment/PullPayment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,16 @@ contract('PullPayment', function ([_, payer, payee1, payee2]) {
(await balanceTracker.delta()).should.be.bignumber.equal(amount);
(await this.contract.payments(payee1)).should.be.bignumber.equal('0');
});

it('can withdraw payment forwarding all gas', async function () {
const balanceTracker = await balance.tracker(payee1);

await this.contract.callTransfer(payee1, amount, { from: payer });
(await this.contract.payments(payee1)).should.be.bignumber.equal(amount);

await this.contract.withdrawPaymentsWithGas(payee1);
frangio marked this conversation as resolved.
Show resolved Hide resolved

(await balanceTracker.delta()).should.be.bignumber.equal(amount);
(await this.contract.payments(payee1)).should.be.bignumber.equal('0');
});
});