ERC777 operators should be internal not private
See original GitHub issueš§ Motivation
The current ERC777 code has a flaw that impacts security and usability.
Here is the code in question.
// This isn't ever read from - it's only used to respond to the defaultOperators query.
address[] private _defaultOperatorsArray;
// Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
mapping(address => bool) private _defaultOperators;
This design makes it impossible to extend the contract by adding or removing default operators and it appears that this is by design, but the thinking behind it is flawed and introduces a security problem.
š Details
Operators especially default operators allow us to extend contracts in interesting and meaningful ways. However the use cases are limited because you either need to declare the operators upfront or convince the individual users to individually approve / reject operators on a case by case basis.
This is a safety issue as well. At present there is no way to blacklist an operator if it is later found to be misbehaving except for each user to reject them one by one.
Making _defaultOperatorsArray and mapping(address => bool) private _defaultOperators internal instead of private would allow for contracts which could add or remove default operators while still providing the user the ability to individually blacklist operators they do not want to interact with.
I realize the logic behind the current design is that users should not be forced to accept new default operators at any random time. Judging from the current design, the thinking appears to be that the users have the option to code review all operators prior to interacting with the ERC777 token.
Ostensibly that is true, but digging deeper it is easy to see many ways this could be abused.
The default operators list could be pre-populated at construction time with either addresses from the developerās own wallet or contract addresses based on forward projecting future contract addresses using something like this https://ethereum.stackexchange.com/questions/24248/how-to-calculate-an-ethereum-contracts-address-during-its-creation-using-the-so
This moots the idea that the user would have complete information prior to interacting with an ERC777 contract and thus it is providing users with a false sense of security, while limiting actual security. This is because, the lack of ability to remove a default operator except on a user by user basis means that if an operator contract is found to be buggy or misbehaving one would need to expend a HUGE amount of effort to reach out to each user to individually blacklist said operator. A lot of damage could be done in the interim.
To wit, I would ask that rather than change the ERC777 standard, we make two small modifications to the existing ERC777.sol which allow contracts to extend ERC777 by simply taking these private vars and declaring them internal.
From there the contract creators can determine best how to add/remove and replace default operators and users will still maintain the ability to veto any operator they are uncomfortable with, but the devs can have an inbuilt process to deal with operators gone awry or adding new operators as opportunities to expand the use of the contract arise.
Issue Analytics
- State:
- Created 4 years ago
- Comments:6 (4 by maintainers)
I donāt see how this is a problem for ERC777s in particular, and not for ERC20s or any other contract. The same goes for vetting the bytecode of a contract: itās already the case that only highly technical users can do it. And itās already the case that some contracts may have external actors with superpowers, be it operators, minters, owners, etc., that those vetting a contract have to pay attention to.
I donāt agree with your points but Iād encourage you to bring it up in https://ethereum-magicians.org. Iām curious about other peopleās opinions.
Hi @sshelton76. Thank you for your report.
We implemented default operators in this way because the ERC777 standard quite unambiguously says so:
Have you raised this concern with the authors of the standard?
I disagree with your following point though:
Prior to interacting the user can definitely see that they have only partial information regarding default operators if any of them either have empty bytecode (except if theyāve selfdestructed) or even if the source code is not available. Based on this they can decide either not to interact with the token or to revoke these operators before doing so. I donāt see how any user can be particularly mislead here.
Let me know your thoughts.