I’m a bit concerned about the
get() function in
It’s purpose, along with
length() is to allow retrieving all elements in the set when the set grows too big and
enumerate() runs out of gas.
As pointed out in the code comments, the order of the elements inside a set is not guaranteed. More specifically each time an element is removed its position is occupied by the one with the highest index.
Looping through all the elements in the set using
get() is not guaranteed to return all the elements, but knowing whether this happened or not will be very difficult for the developer.
I’m very concerned about developers thinking that iterating over an
EnumerableSet is fine, and that leading to bugs, vulnerabilities, and a lot of frustration.
I can see two alternatives to
enumerate() when the set grows too big for a block.
- Implement a state machine, and lock down the set while being iterated.
- Encourage developers to emit events when changing the set, and keeping track of the set contents off-chain.
The first approach is the one I would take when I need to iterate over large data sets to do a state change for each set element. For example when distributing dividends for all token holders.
The second approach is the one I would take when I need to reveal the contents of the set to the front end.
I would leave
EnumerableSet.sol, but I would remove
get() after pointing out the limitations carefully.