From e4a8a5533e8d3157ec398d2e5597cdd81410e4cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 24 Jan 2020 14:56:29 -0300 Subject: [PATCH 1/6] 2.5.0-rc.0 --- contracts/package.json | 2 +- ethpm.json | 2 +- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index ef570eeef..a259625a6 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/contracts", - "version": "2.4.0", + "version": "2.5.0-rc.0", "description": "Secure Smart Contract library for Solidity", "files": [ "**/*.sol", diff --git a/ethpm.json b/ethpm.json index 7593e5c25..ae61a00b0 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.4.0", + "version": "2.5.0-rc.0", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index ce7cc6f00..d9b5f8ef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.4.0", + "version": "2.5.0-rc.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 74d5d2f1e..7c3d39875 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.4.0", + "version": "2.5.0-rc.0", "description": "Secure Smart Contract library for Solidity", "files": [ "/contracts/**/*.sol", From d775e315cca96bc91934c5f3b6d65292042a8593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 24 Jan 2020 15:07:37 -0300 Subject: [PATCH 2/6] Update package homepage. --- contracts/package.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index a259625a6..e5b29096d 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -28,5 +28,5 @@ "bugs": { "url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" }, - "homepage": "https://github.com/OpenZeppelin/openzeppelin-contracts" + "homepage": "https://openzeppelin.com/contracts/" } diff --git a/package.json b/package.json index 7c3d39875..381c2daee 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "bugs": { "url": "https://github.com/OpenZeppelin/openzeppelin-contracts/issues" }, - "homepage": "https://github.com/OpenZeppelin/openzeppelin-contracts", + "homepage": "https://openzeppelin.com/contracts/", "devDependencies": { "@openzeppelin/cli": "^2.5.3", "@openzeppelin/gsn-helpers": "^0.2.3", From 0ac83ce289987ad4250f67e5fc61af0f47650096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Cuesta=20Ca=C3=B1ada?= <38806121+albertocuestacanada@users.noreply.github.com> Date: Thu, 30 Jan 2020 18:42:21 +0000 Subject: [PATCH 3/6] Fix EnumerableSetMock for 2.5.rc1 (#2069) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Drafted Enumerable.sol. * Drafted test framework. * Tweaked the tests to follow oz structure. * Coded EnumerableSet. * Moved EnumerableSet to `utils`. * Fixed linting. * Improved comments. * Tweaked contract description. * Renamed struct to AddressSet. * Relaxed version pragma to 0.5.0 * Removed events. * Revert on useless operations. * Small comment. * Created AddressSet factory method. * Failed transactions return false. * Transactions now return false on failure. * Remove comments from mock * Rename mock functions * Adapt tests to code style, use test-helpers * Fix bug in remove, improve tests. * Add changelog entry * Add entry on Utils doc * Add optimization for removal of last slot * Update docs * Fix headings of utilities documentation * Simplified mock. * Fixed comment. * Revert "Fixed comment." This reverts commit 39627f9a6f90d48be20ca1449fe03e1699b48173. * Revert "Simplified mock." This reverts commit 67468e464b038736251f18e1dc2e368c9091a87a. * Simplified mock. Co-authored-by: Nicolás Venturo (cherry picked from commit 8975289c6b85caeedae815ebada00c6236a4ecce) --- contracts/mocks/EnumerableSetMock.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/mocks/EnumerableSetMock.sol b/contracts/mocks/EnumerableSetMock.sol index 407ee6c15..4ef4fa04a 100644 --- a/contracts/mocks/EnumerableSetMock.sol +++ b/contracts/mocks/EnumerableSetMock.sol @@ -14,20 +14,20 @@ contract EnumerableSetMock{ } function contains(address value) public view returns (bool) { - return EnumerableSet.contains(set, value); + return set.contains(value); } function add(address value) public { - bool result = EnumerableSet.add(set, value); + bool result = set.add(value); emit TransactionResult(result); } function remove(address value) public { - bool result = EnumerableSet.remove(set, value); + bool result = set.remove(value); emit TransactionResult(result); } function enumerate() public view returns (address[] memory) { - return EnumerableSet.enumerate(set); + return set.enumerate(); } } From 1b938e39a82bfea896f45408113f9ef74284461f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Tue, 4 Feb 2020 19:15:32 -0300 Subject: [PATCH 4/6] EnumerableSet improvements (#2077) * Remove newAddressSet * Add count and get functions. * Fix lint (cherry picked from commit 7988c044e075024e6018527fddd83c70cc6ec8f0) --- contracts/mocks/EnumerableSetMock.sol | 12 +++++--- contracts/utils/EnumerableSet.sol | 43 ++++++++++++++++++++------- test/utils/EnumerableSet.test.js | 36 +++++++++++++--------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/contracts/mocks/EnumerableSetMock.sol b/contracts/mocks/EnumerableSetMock.sol index 4ef4fa04a..d2dc13d1e 100644 --- a/contracts/mocks/EnumerableSetMock.sol +++ b/contracts/mocks/EnumerableSetMock.sol @@ -9,10 +9,6 @@ contract EnumerableSetMock{ EnumerableSet.AddressSet private set; - constructor() public { - set = EnumerableSet.newAddressSet(); - } - function contains(address value) public view returns (bool) { return set.contains(value); } @@ -30,4 +26,12 @@ contract EnumerableSetMock{ function enumerate() public view returns (address[] memory) { return set.enumerate(); } + + function length() public view returns (uint256) { + return set.length(); + } + + function get(uint256 index) public view returns (address) { + return set.get(index); + } } diff --git a/contracts/utils/EnumerableSet.sol b/contracts/utils/EnumerableSet.sol index 6798a30df..8ed12155c 100644 --- a/contracts/utils/EnumerableSet.sol +++ b/contracts/utils/EnumerableSet.sol @@ -29,17 +29,6 @@ library EnumerableSet { address[] values; } - /** - * @dev Creates a new empty address set. - */ - function newAddressSet() - internal - pure - returns (AddressSet memory) - { - return AddressSet({values: new address[](0)}); - } - /** * @dev Add a value to a set. O(1). * Returns false if the value was already in the set. @@ -105,6 +94,9 @@ library EnumerableSet { * @dev Returns an array with all values in the set. O(N). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. + + * WARNING: This function may run out of gas on large sets: use {length} and + * {get} instead in these cases. */ function enumerate(AddressSet storage set) internal @@ -117,4 +109,33 @@ library EnumerableSet { } return output; } + + /** + * @dev Returns the number of elements on the set. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + */ + function length(AddressSet storage set) + internal + view + returns (uint256) + { + return set.values.length; + } + + /** @dev Returns the element stored at position `index` in the set. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function get(AddressSet storage set, uint256 index) + internal + view + returns (address) + { + return set.values[index]; + } } diff --git a/test/utils/EnumerableSet.test.js b/test/utils/EnumerableSet.test.js index 0162da5fa..137c80518 100644 --- a/test/utils/EnumerableSet.test.js +++ b/test/utils/EnumerableSet.test.js @@ -11,29 +11,39 @@ describe('EnumerableSet', function () { this.set = await EnumerableSetMock.new(); }); + async function expectMembersMatch (set, members) { + await Promise.all(members.map(async account => + expect(await set.contains(account)).to.equal(true) + )); + + expect(await set.enumerate()).to.have.same.members(members); + + expect(await set.length()).to.bignumber.equal(members.length.toString()); + + expect(await Promise.all([...Array(members.length).keys()].map(index => + set.get(index) + ))).to.have.same.members(members); + } + it('starts empty', async function () { expect(await this.set.contains(accountA)).to.equal(false); - expect(await this.set.enumerate()).to.have.same.members([]); + + await expectMembersMatch(this.set, []); }); it('adds a value', async function () { const receipt = await this.set.add(accountA); expectEvent(receipt, 'TransactionResult', { result: true }); - expect(await this.set.contains(accountA)).to.equal(true); - expect(await this.set.enumerate()).to.have.same.members([ accountA ]); + await expectMembersMatch(this.set, [accountA]); }); it('adds several values', async function () { await this.set.add(accountA); await this.set.add(accountB); - expect(await this.set.contains(accountA)).to.equal(true); - expect(await this.set.contains(accountB)).to.equal(true); - + await expectMembersMatch(this.set, [accountA, accountB]); expect(await this.set.contains(accountC)).to.equal(false); - - expect(await this.set.enumerate()).to.have.same.members([ accountA, accountB ]); }); it('returns false when adding elements already in the set', async function () { @@ -42,7 +52,7 @@ describe('EnumerableSet', function () { const receipt = (await this.set.add(accountA)); expectEvent(receipt, 'TransactionResult', { result: false }); - expect(await this.set.enumerate()).to.have.same.members([ accountA ]); + await expectMembersMatch(this.set, [accountA]); }); it('removes added values', async function () { @@ -52,7 +62,7 @@ describe('EnumerableSet', function () { expectEvent(receipt, 'TransactionResult', { result: true }); expect(await this.set.contains(accountA)).to.equal(false); - expect(await this.set.enumerate()).to.have.same.members([]); + await expectMembersMatch(this.set, []); }); it('returns false when removing elements not in the set', async function () { @@ -99,10 +109,8 @@ describe('EnumerableSet', function () { // [A, C] - expect(await this.set.contains(accountA)).to.equal(true); - expect(await this.set.contains(accountB)).to.equal(false); - expect(await this.set.contains(accountC)).to.equal(true); + await expectMembersMatch(this.set, [accountA, accountC]); - expect(await this.set.enumerate()).to.have.same.members([ accountA, accountC ]); + expect(await this.set.contains(accountB)).to.equal(false); }); }); From 941d305044691bbe6ceae5bd7e8eaaf737f1a932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Tue, 4 Feb 2020 19:35:31 -0300 Subject: [PATCH 5/6] Update docs --- contracts/utils/EnumerableSet.sol | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/contracts/utils/EnumerableSet.sol b/contracts/utils/EnumerableSet.sol index 8ed12155c..2ea0d169e 100644 --- a/contracts/utils/EnumerableSet.sol +++ b/contracts/utils/EnumerableSet.sol @@ -13,8 +13,7 @@ pragma solidity ^0.5.0; * * As of v2.5.0, only `address` sets are supported. * - * Include with `using EnumerableSet for EnumerableSet.AddressSet;`, and use - * {newAddressSet} to create a new `AddressSet`. + * Include with `using EnumerableSet for EnumerableSet.AddressSet;`. * * _Available since v2.5.0._ * @@ -112,8 +111,6 @@ library EnumerableSet { /** * @dev Returns the number of elements on the set. O(1). - * Note that there are no guarantees on the ordering of values inside the - * array, and it may change when more values are added or removed. */ function length(AddressSet storage set) internal @@ -128,8 +125,8 @@ library EnumerableSet { * array, and it may change when more values are added or removed. * * Requirements: - * - * - `index` must be strictly less than {length}. + * + * - `index` must be strictly less than {length}. */ function get(AddressSet storage set, uint256 index) internal From 58a3368215581509d05bd3ec4d53cd381c9bb40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Tue, 4 Feb 2020 19:39:23 -0300 Subject: [PATCH 6/6] 2.5.0 --- 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 e0490ea4a..b446128f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 2.5.0 (unreleased) +## 2.5.0 (2020-02-04) ### New features * `SafeCast.toUintXX`: new library for integer downcasting, which allows for safe operation on smaller types (e.g. `uint32`) when combined with `SafeMath`. ([#1926](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1926)) diff --git a/contracts/package.json b/contracts/package.json index e5b29096d..ba9393b92 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/contracts", - "version": "2.5.0-rc.0", + "version": "2.5.0", "description": "Secure Smart Contract library for Solidity", "files": [ "**/*.sol", diff --git a/ethpm.json b/ethpm.json index ae61a00b0..60c6c669b 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "zeppelin", - "version": "2.5.0-rc.0", + "version": "2.5.0", "description": "Secure Smart Contract library for Solidity", "authors": [ "OpenZeppelin Community " diff --git a/package-lock.json b/package-lock.json index d9b5f8ef7..dfcb24dfb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.5.0-rc.0", + "version": "2.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 381c2daee..34207bbcb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openzeppelin-solidity", - "version": "2.5.0-rc.0", + "version": "2.5.0", "description": "Secure Smart Contract library for Solidity", "files": [ "/contracts/**/*.sol",