-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Description
This is a feature request, and I wanted to know what your thoughts about it may be. Apologies in advance if this has already been discussed (couldn't find anything related here).
It'd be useful to be able to declare a sort-of contract-level modifier, that allows to inject code that executes on every call received by the contract, and executes based on raw msg data, signature, etc. This allows to provide a global behaviour to the contract, without needing to manually add a modifier to every external function, which is error-prone if one is forgotten.
We have identified two main use cases so far where this feature would be helpful:
-
Global pausable contract: we have a Pausable behaviour in OpenZeppelin, which requires the user to add
whenNotPausedmodifiers to every public function that must be blocked. It would be much easier if the user of the contract could just add a global behaviour that blocks every external call to the contract if it's paused, except for specificunpausecalls that could be detected manually via msg.sig in the global modifier. -
Block calls to proxy backing implementations: we are working heavily on proxies at the moment, which depend on a backing implementation where all calls are delegated. However, it would be interesting to be able to lock the implementations, so any direct call made to them (without going via a proxy) is automatically reverted, in order to prevent confusions from users that inadvertently call those contracts directly. Doing this via a contract-level modifier that checks that
this != implementationAddresson every call is trivial, while adding this check manually to every public function is cumbersome.
Please let me know what you think about the feature, and whether you would consider adding it to the roadmap, or accept a pull request with its implementation.