EnumerableSet.clear()
See original GitHub issue🧐 Motivation Use case: I need to store a bunch of approvals in a set and once the number of approvals reach a specific length, I need to execute an operation and clear all the approvals.
📝 Details
Right now, it is possible to clear the set with this code:
address[] memory values = approvals.values();
for (uint256 i = 0; i < values.length; i++) {
approvals.remove(values[i]);
}
but it is rather inefficient because each call to .remove()
does .pop()
and multiple storage reads/writes.
The implementation of .clear()
might look like this:
function clear(Set storage set) private {
for (uint256 i = 0; i < set._values.length; i++) {
set._indexes[set._values[i]] = 0;
}
// this line is dangerous as it might consume unbounded amount of gas
set._values = new bytes32[](0);
}
If set._values = new bytes32[](0);
is too dangerous, another way to implement .clear()
is to make another struct
with .clear()
method:
struct ClearableAddressSet {
uint256 _setId;
// setId => AddressSet
mapping(uint256 => AddressSet) _sets;
}
// delegate all functions
function add(ClearableAddressSet storage set, address value) internal returns (bool) {
return set._sets[set._setId].add(value);
}
function clear() internal {
// by incrementing `_setId`, a new set is "created".
set._setId++;
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Utilities - OpenZeppelin Docs
EnumerableSet : like EnumerableMap , but for sets. Can be used to store privileged accounts, issued IDs, etc. Because Solidity does not support...
Read more >EnumerableSet vs Access Control in Openzeppelin
Using enumerable sets works similar (you are storing the indexes that correspond to the addresses). There shouldn't be a reason for you to ......
Read more >Address 0x4F290e83B414097C107F5AD483a9ae15434B43d3
function totalSupply() external view returns (uint256); ... library EnumerableSet { // To implement this library for multiple types with as ...
Read more >Enumerable.Empty<TResult> Method (System.Linq)
Generic.IEnumerable<TResult> Empty<TResult> (); static member Empty : unit -> seq<'Result> Public Function Empty(Of TResult) () As IEnumerable(Of TResult) ...
Read more >Ethereum Contract Diff Checker - Etherscan
Increaser; using SignatureChecker for EnumerableSet. ... If true, future calls to mint() with the same parameters will fail. @dev In production we will ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Yeah I think the best option is to use an array of EnumerableSet and just move on to the next one when you clear.
I don’t think it makes sense for us to provide this pattern out of the box.
Agree with @envatic, using an array panics, though wasn’t necessarily in the case of an upgradable contract. Panic exception is:
Using a mapping instead worked 👍