Add BytesSet (#2395)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
@ -4,6 +4,7 @@
|
||||
|
||||
* `Address`: added `functionStaticCall` and `functionDelegateCall`, similar to the existing `functionCall`. ([#2333](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2333))
|
||||
* `TimelockController`: added a contract to augment access control schemes with a delay. ([#2364](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2364))
|
||||
* `EnumerableSet`: added `BytesSet`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395))
|
||||
|
||||
## 3.2.0 (2020-09-10)
|
||||
|
||||
|
||||
@ -4,6 +4,37 @@ pragma solidity ^0.6.0;
|
||||
|
||||
import "../utils/EnumerableSet.sol";
|
||||
|
||||
// Bytes32Set
|
||||
contract EnumerableBytes32SetMock {
|
||||
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||
|
||||
event OperationResult(bool result);
|
||||
|
||||
EnumerableSet.Bytes32Set private _set;
|
||||
|
||||
function contains(bytes32 value) public view returns (bool) {
|
||||
return _set.contains(value);
|
||||
}
|
||||
|
||||
function add(bytes32 value) public {
|
||||
bool result = _set.add(value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function remove(bytes32 value) public {
|
||||
bool result = _set.remove(value);
|
||||
emit OperationResult(result);
|
||||
}
|
||||
|
||||
function length() public view returns (uint256) {
|
||||
return _set.length();
|
||||
}
|
||||
|
||||
function at(uint256 index) public view returns (bytes32) {
|
||||
return _set.at(index);
|
||||
}
|
||||
}
|
||||
|
||||
// AddressSet
|
||||
contract EnumerableAddressSetMock {
|
||||
using EnumerableSet for EnumerableSet.AddressSet;
|
||||
|
||||
@ -23,8 +23,8 @@ pragma solidity ^0.6.0;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256`
|
||||
* (`UintSet`) are supported.
|
||||
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
|
||||
* and `uint256` (`UintSet`) are supported.
|
||||
*/
|
||||
library EnumerableSet {
|
||||
// To implement this library for multiple types with as little code
|
||||
@ -132,6 +132,60 @@ library EnumerableSet {
|
||||
return set._values[index];
|
||||
}
|
||||
|
||||
// Bytes32Set
|
||||
|
||||
struct Bytes32Set {
|
||||
Set _inner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add a value to a set. O(1).
|
||||
*
|
||||
* Returns true if the value was added to the set, that is if it was not
|
||||
* already present.
|
||||
*/
|
||||
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
|
||||
return _add(set._inner, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Removes a value from a set. O(1).
|
||||
*
|
||||
* Returns true if the value was removed from the set, that is if it was
|
||||
* present.
|
||||
*/
|
||||
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
|
||||
return _remove(set._inner, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns true if the value is in the set. O(1).
|
||||
*/
|
||||
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
|
||||
return _contains(set._inner, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the number of values in the set. O(1).
|
||||
*/
|
||||
function length(Bytes32Set storage set) internal view returns (uint256) {
|
||||
return _length(set._inner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value 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 at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
|
||||
return _at(set._inner, index);
|
||||
}
|
||||
|
||||
// AddressSet
|
||||
|
||||
struct AddressSet {
|
||||
|
||||
@ -1,14 +1,28 @@
|
||||
const { BN } = require('@openzeppelin/test-helpers');
|
||||
|
||||
const EnumerableBytes32SetMock = artifacts.require('EnumerableBytes32SetMock');
|
||||
const EnumerableAddressSetMock = artifacts.require('EnumerableAddressSetMock');
|
||||
const EnumerableUintSetMock = artifacts.require('EnumerableUintSetMock');
|
||||
|
||||
const { shouldBehaveLikeSet } = require('./EnumerableSet.behavior');
|
||||
|
||||
contract('EnumerableSet', function (accounts) {
|
||||
// Bytes32Set
|
||||
describe('EnumerableBytes32Set', function () {
|
||||
const bytesA = '0xdeadbeef'.padEnd(66, '0');
|
||||
const bytesB = '0x0123456789'.padEnd(66, '0');
|
||||
const bytesC = '0x42424242'.padEnd(66, '0');
|
||||
|
||||
beforeEach(async function () {
|
||||
this.set = await EnumerableBytes32SetMock.new();
|
||||
});
|
||||
|
||||
shouldBehaveLikeSet(bytesA, bytesB, bytesC);
|
||||
});
|
||||
|
||||
// AddressSet
|
||||
describe('EnumerableAddressSet', function () {
|
||||
const [ accountA, accountB, accountC ] = accounts;
|
||||
const [accountA, accountB, accountC] = accounts;
|
||||
|
||||
beforeEach(async function () {
|
||||
this.set = await EnumerableAddressSetMock.new();
|
||||
|
||||
Reference in New Issue
Block a user