From c75b01691973b93f00fffa41a406f4e3d923b2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 24 Apr 2020 15:33:22 -0300 Subject: [PATCH 1/4] Add missing requirements to ERC777 (#2212) * Restore _approve check for zero sender * Add non-zero operator check to _send --- contracts/mocks/ERC777Mock.sol | 4 ++++ contracts/token/ERC777/ERC777.sol | 10 +++++++--- test/token/ERC777/ERC777.test.js | 22 ++++++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/contracts/mocks/ERC777Mock.sol b/contracts/mocks/ERC777Mock.sol index 314be2ea735..42a41c1c2d2 100644 --- a/contracts/mocks/ERC777Mock.sol +++ b/contracts/mocks/ERC777Mock.sol @@ -23,4 +23,8 @@ contract ERC777Mock is Context, ERC777 { ) public { _mint(operator, to, amount, userData, operatorData); } + + function approveInternal(address holder, address spender, uint256 value) public { + _approve(holder, spender, value); + } } diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index 2a91f25df27..0c6f9f0a64c 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -352,6 +352,7 @@ contract ERC777 is Context, IERC777, IERC20 { ) internal { + require(operator != address(0), "ERC777: operator is the zero address"); require(from != address(0), "ERC777: send from the zero address"); require(to != address(0), "ERC777: send to the zero address"); @@ -408,10 +409,13 @@ contract ERC777 is Context, IERC777, IERC20 { emit Transfer(from, to, amount); } + /** + * @dev See {ERC20-_approve}. + * + * Note that accounts cannot have allowance issued by their operators. + */ function _approve(address holder, address spender, uint256 value) internal { - // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is - // currently unnecessary. - //require(holder != address(0), "ERC777: approve from the zero address"); + require(holder != address(0), "ERC777: approve from the zero address"); require(spender != address(0), "ERC777: approve to the zero address"); _allowances[holder][spender] = value; diff --git a/test/token/ERC777/ERC777.test.js b/test/token/ERC777/ERC777.test.js index 830e406ac92..e1f55e3326b 100644 --- a/test/token/ERC777/ERC777.test.js +++ b/test/token/ERC777/ERC777.test.js @@ -1,6 +1,7 @@ const { accounts, contract, web3 } = require('@openzeppelin/test-environment'); -const { BN, expectEvent, expectRevert, singletons } = require('@openzeppelin/test-helpers'); +const { BN, constants, expectEvent, expectRevert, singletons } = require('@openzeppelin/test-helpers'); +const { ZERO_ADDRESS } = constants; const { expect } = require('chai'); @@ -15,6 +16,7 @@ const { const { shouldBehaveLikeERC20, + shouldBehaveLikeERC20Approve, } = require('../ERC20/ERC20.behavior'); const ERC777 = contract.fromArtifact('ERC777Mock'); @@ -40,7 +42,23 @@ describe('ERC777', function () { this.token = await ERC777.new(holder, initialSupply, name, symbol, defaultOperators); }); - shouldBehaveLikeERC20('ERC777', initialSupply, holder, anyone, defaultOperatorA); + describe('as an ERC20 token', function () { + shouldBehaveLikeERC20('ERC777', initialSupply, holder, anyone, defaultOperatorA); + + describe('_approve', function () { + shouldBehaveLikeERC20Approve('ERC777', holder, anyone, initialSupply, function (owner, spender, amount) { + return this.token.approveInternal(owner, spender, amount); + }); + + describe('when the owner is the zero address', function () { + it('reverts', async function () { + await expectRevert(this.token.approveInternal(ZERO_ADDRESS, anyone, initialSupply), + 'ERC777: approve from the zero address' + ); + }); + }); + }); + }); it.skip('does not emit AuthorizedOperator events for default operators', async function () { expectEvent.not.inConstructor(this.token, 'AuthorizedOperator'); // This helper needs to be implemented From 3843c9beb780e41274d0d35ac71de1f3d2a40276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 24 Apr 2020 15:34:38 -0300 Subject: [PATCH 2/4] Add changelog entry --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b446128f402..0140d4450c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2.5.1 (unreleased) + +### Bugfixes + * `ERC777`: fixed the `_send` and `_approve` internal functions not validating some of their arguments for non-zero addresses. ([#2212](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2212)) + ## 2.5.0 (2020-02-04) ### New features From 837828967a9831e4333d5fb9edefb200a357d24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 24 Apr 2020 15:57:33 -0300 Subject: [PATCH 3/4] 2.5.1 --- CHANGELOG.md | 2 +- contracts/package.json | 2 +- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0140d4450c3..2ac615f315d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 2.5.1 (unreleased) +## 2.5.1 (2020-04-24) ### Bugfixes * `ERC777`: fixed the `_send` and `_approve` internal functions not validating some of their arguments for non-zero addresses. ([#2212](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2212)) diff --git a/contracts/package.json b/contracts/package.json index ba9393b9270..17f6d7894d7 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/contracts", - "version": "2.5.0", + "version": "2.5.1", "description": "Secure Smart Contract library for Solidity", "files": [ "**/*.sol", diff --git a/ethpm.json b/ethpm.json index 60c6c669bb8..8eab2986aec 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.5.0", + "version": "2.5.1", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index dfcb24dfb27..69873260fa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.5.0", + "version": "2.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 34207bbcb50..439333e3ba4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.5.0", + "version": "2.5.1", "description": "Secure Smart Contract library for Solidity", "files": [ "/contracts/**/*.sol", From d0f67f99a7028ff097d0a21ae25f3d21c1e64c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 24 Apr 2020 16:08:00 -0300 Subject: [PATCH 4/4] Add changelog entry --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2fdc0a66a4..85f5b9cdea7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 3.0.1 (unreleased) + +### Bugfixes + * `ERC777`: fixed the `_approve` internal function not validating some of their arguments for non-zero addresses. ([#2213](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2213)) + ## 3.0.0 (2020-04-20) ### New features