From ec3b1cf10845f971951bf1bbcb369bf22a74b8ca Mon Sep 17 00:00:00 2001 From: alonbg Date: Fri, 22 Apr 2022 14:37:34 +0300 Subject: [PATCH 1/7] refactor release functions move payment to unclaimed functions --- CHANGELOG.md | 1 + contracts/finance/PaymentSplitter.sol | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79b86c06763..a510853e7a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* `PaymentSplitter`: refactor payment into public `releasable` functions ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) * `Clones`: optimize clone creation ([#3329](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3329)) * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) * `CrossChainEnabledPolygonChild`: replace the `require` statement with the custom error `NotCrossChainCall`. ([#3380](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3380)) diff --git a/contracts/finance/PaymentSplitter.sol b/contracts/finance/PaymentSplitter.sol index 94d2ab827c5..f6a8e39745a 100644 --- a/contracts/finance/PaymentSplitter.sol +++ b/contracts/finance/PaymentSplitter.sol @@ -120,6 +120,23 @@ contract PaymentSplitter is Context { return _payees[index]; } + /** + * @dev Getter for the amount of payee's unclaimed Ether. + */ + function releasable(address account) public view returns (uint256) { + uint256 totalReceived = address(this).balance + totalReleased(); + return _pendingPayment(account, totalReceived, released(account)); + } + + /** + * @dev Getter for the amount of payee's unclaimed `token` tokens. `token` should be the address of an + * IERC20 contract. + */ + function releasable(IERC20 token, address account) public view returns (uint256) { + uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token); + return _pendingPayment(account, totalReceived, released(token, account)); + } + /** * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the * total shares and their previous withdrawals. @@ -127,8 +144,7 @@ contract PaymentSplitter is Context { function release(address payable account) public virtual { require(_shares[account] > 0, "PaymentSplitter: account has no shares"); - uint256 totalReceived = address(this).balance + totalReleased(); - uint256 payment = _pendingPayment(account, totalReceived, released(account)); + uint256 payment = releasable(account); require(payment != 0, "PaymentSplitter: account is not due payment"); @@ -147,8 +163,7 @@ contract PaymentSplitter is Context { function release(IERC20 token, address account) public virtual { require(_shares[account] > 0, "PaymentSplitter: account has no shares"); - uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token); - uint256 payment = _pendingPayment(account, totalReceived, released(token, account)); + uint256 payment = releasable(token, account); require(payment != 0, "PaymentSplitter: account is not due payment"); From 2ae64e73064c258cffa65ac1262eb77fd6b3292e Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Mon, 30 May 2022 22:19:07 -0300 Subject: [PATCH 2/7] rename unclaimed -> releasable --- contracts/finance/PaymentSplitter.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/finance/PaymentSplitter.sol b/contracts/finance/PaymentSplitter.sol index f6a8e39745a..69786e3979c 100644 --- a/contracts/finance/PaymentSplitter.sol +++ b/contracts/finance/PaymentSplitter.sol @@ -121,7 +121,7 @@ contract PaymentSplitter is Context { } /** - * @dev Getter for the amount of payee's unclaimed Ether. + * @dev Getter for the amount of payee's releasable Ether. */ function releasable(address account) public view returns (uint256) { uint256 totalReceived = address(this).balance + totalReleased(); @@ -129,7 +129,7 @@ contract PaymentSplitter is Context { } /** - * @dev Getter for the amount of payee's unclaimed `token` tokens. `token` should be the address of an + * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an * IERC20 contract. */ function releasable(IERC20 token, address account) public view returns (uint256) { From 88d518e7f37a3e5712af08907acf31a86bc900e7 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Mon, 30 May 2022 22:19:45 -0300 Subject: [PATCH 3/7] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a510853e7a2..f2e2699298a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * `MerkleProof`: add `multiProofVerify` to prove multiple values are part of a Merkle tree. ([#3276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3276)) * `ERC721`, `ERC1155`: simplified revert reasons. ([#3254](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3254)) * `ERC721`: removed redundant require statement. ([#3434](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3434)) + * `PaymentSplitter`: add `releasable` getter. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) ## 4.6.0 (2022-04-26) From 15db8cba6ae119dbe813e6c9bc8a387d088da9e1 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Mon, 30 May 2022 22:34:07 -0300 Subject: [PATCH 4/7] remove bad async --- test/finance/PaymentSplitter.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/finance/PaymentSplitter.test.js b/test/finance/PaymentSplitter.test.js index fdb81f6104e..8a7985f1e8b 100644 --- a/test/finance/PaymentSplitter.test.js +++ b/test/finance/PaymentSplitter.test.js @@ -65,7 +65,7 @@ contract('PaymentSplitter', function (accounts) { })); }); - describe('accepts payments', async function () { + describe('accepts payments', function () { it('Ether', async function () { await send.ether(owner, this.contract.address, amount); @@ -79,7 +79,7 @@ contract('PaymentSplitter', function (accounts) { }); }); - describe('shares', async function () { + describe('shares', function () { it('stores shares if address is payee', async function () { expect(await this.contract.shares(payee1)).to.be.bignumber.not.equal('0'); }); @@ -89,8 +89,8 @@ contract('PaymentSplitter', function (accounts) { }); }); - describe('release', async function () { - describe('Ether', async function () { + describe('release', function () { + describe('Ether', function () { it('reverts if no funds to claim', async function () { await expectRevert(this.contract.release(payee1), 'PaymentSplitter: account is not due payment', @@ -104,7 +104,7 @@ contract('PaymentSplitter', function (accounts) { }); }); - describe('Token', async function () { + describe('Token', function () { it('reverts if no funds to claim', async function () { await expectRevert(this.contract.release(this.token.address, payee1), 'PaymentSplitter: account is not due payment', @@ -119,7 +119,7 @@ contract('PaymentSplitter', function (accounts) { }); }); - describe('distributes funds to payees', async function () { + describe('distributes funds to payees', function () { it('Ether', async function () { await send.ether(payer1, this.contract.address, amount); From 76240b93acbbe847c78a9343494ecd6485b96ffb Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Tue, 31 May 2022 15:58:35 -0300 Subject: [PATCH 5/7] add tests for released and releasable --- test/finance/PaymentSplitter.test.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/finance/PaymentSplitter.test.js b/test/finance/PaymentSplitter.test.js index 8a7985f1e8b..2fa7a26fa82 100644 --- a/test/finance/PaymentSplitter.test.js +++ b/test/finance/PaymentSplitter.test.js @@ -62,6 +62,7 @@ contract('PaymentSplitter', function (accounts) { await Promise.all(this.payees.map(async (payee, index) => { expect(await this.contract.payee(index)).to.equal(payee); expect(await this.contract.released(payee)).to.be.bignumber.equal('0'); + expect(await this.contract.releasable(payee)).to.be.bignumber.equal('0'); })); }); @@ -119,6 +120,26 @@ contract('PaymentSplitter', function (accounts) { }); }); + describe('tracks releasable and released', function () { + it('Ether', async function () { + await send.ether(payer1, this.contract.address, amount); + const payment = amount.divn(10); + expect(await this.contract.releasable(payee2)).to.be.bignumber.equal(payment); + await this.contract.release(payee2); + expect(await this.contract.releasable(payee2)).to.be.bignumber.equal('0'); + expect(await this.contract.released(payee2)).to.be.bignumber.equal(payment); + }); + + it('Token', async function () { + await this.token.transfer(this.contract.address, amount, { from: owner }); + const payment = amount.divn(10); + expect(await this.contract.releasable(this.token.address, payee2, {})).to.be.bignumber.equal(payment); + await this.contract.release(this.token.address, payee2); + expect(await this.contract.releasable(this.token.address, payee2, {})).to.be.bignumber.equal('0'); + expect(await this.contract.released(this.token.address, payee2)).to.be.bignumber.equal(payment); + }); + }); + describe('distributes funds to payees', function () { it('Ether', async function () { await send.ether(payer1, this.contract.address, amount); From 0accd38e6d62f3e6d74b880a66e0e59ed495b76b Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 31 May 2022 21:11:25 +0200 Subject: [PATCH 6/7] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2e2699298a..0beb40cad91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ ## Unreleased -* `PaymentSplitter`: refactor payment into public `releasable` functions ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) * `Clones`: optimize clone creation ([#3329](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3329)) * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) * `CrossChainEnabledPolygonChild`: replace the `require` statement with the custom error `NotCrossChainCall`. ([#3380](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3380)) @@ -14,7 +13,7 @@ * `MerkleProof`: add `multiProofVerify` to prove multiple values are part of a Merkle tree. ([#3276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3276)) * `ERC721`, `ERC1155`: simplified revert reasons. ([#3254](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3254)) * `ERC721`: removed redundant require statement. ([#3434](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3434)) - * `PaymentSplitter`: add `releasable` getter. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) + * `PaymentSplitter`: add public `releasable` getters. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) ## 4.6.0 (2022-04-26) From 761b95724dcfe20de11fabe53955d363014db435 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 31 May 2022 21:13:46 +0200 Subject: [PATCH 7/7] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0beb40cad91..985bebf8887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ * `MerkleProof`: add `multiProofVerify` to prove multiple values are part of a Merkle tree. ([#3276](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3276)) * `ERC721`, `ERC1155`: simplified revert reasons. ([#3254](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3254)) * `ERC721`: removed redundant require statement. ([#3434](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3434)) - * `PaymentSplitter`: add public `releasable` getters. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) + * `PaymentSplitter`: add `releasable` getters. ([#3350](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3350)) ## 4.6.0 (2022-04-26)