Search code examples
ethereumsolidityaccess-modifiers

Solidity: how to apply OR operator in function modifiers?


I have a contract with a private Enum state that has three options: CREATED, VALID and TERMINATED. This contract has a function withdrawn that can only be called by the contract creator, and a function terminatine that can only be called by a third-party that is set during the contract creation. Both functions have a modifier requireState(State.VALID) so they can only be called after the contract is in the VALID state.

The issue is that I want to configure the withdrawn function so it can be called if the state is set to VALID OR TERMINATED. How can I do that?

My modifier is shown below:

enum State { CREATED, VALID, TERMINATED }
State state;

modifier requireState(State _state) {
   require(state == _state);
   _;
}

I'm on Solidity 0.8.1.


Solution

  • All modifiers of a function need to pass before this function is executed. So they always act as if they were connected by AND operators.

    You can create a new modifier that accepts multiple values and performs an OR operation on them.

    However, you'd need to either use a fixed amount of arguments or a fixed-length array, because Solidity currently doesn't allow one-line declaration of a dynamic length array.

    Example: [State.VALID, State.TERMINATED] is declaration of a fixed-length array, so it doesn't match with State[] dynamic-length definition.

    modifier requireAnyOfStates(State[2] memory _states) {
        require(_states[0] == state || _states[1] == state);
        _;
    }
        
    function foo() external requireAnyOfStates([State.VALID, State.TERMINATED]) {
    }
    

    But much simpler approach in this case is to just use a require statement in your function instead of a modifier.

    function foo() external {
        require(state == State.VALID || state == State.TERMINATED);
    }