0

Came across this little confusing situation of underscores in modifier so I want to post it here to check if my understanding is correct.

contract whatever{
    bool public locked;
    uint public x = 10;

    modifier noReentrancy() {
        require(!locked, "No reentrancy");

        locked = true;
        _;
        locked = false;
    }

    function decrement(uint i) public noReentrancy {
        x -= i;

        if (i > 1) {
            decrement(i - 1);
        }
    }
}

the underscore in the middle of the modifier function is little trick to me. so my understanding is: when modifier is first ran, the value of locked is true. then the underscore means run the function code which is x-= i ... this will trigger the if condition and if i >i then the same function will be called again while being executed (the point of noReentry modifier) then the value of locked will be false which will trigger the function decrement() to stop. the value of x will be 10. so unless the value of i is 1 or 0 (so the if condition is not triggered), the value of x will always be 10 in this case?

thank you for your patience!

2

1 Answer 1

0

The underscore represents the rest of the function code. Whatever is before the underscore is ran before the function code, and whatever is after is ran after

( By the way, in the case where a function uses multiple modifier, they're ran in the order they're declared in the code (and not in the function declaration) for example :

modifier isA{
//...
}
modifier isB{
//...
}
function modified() isB isA external {
// isA is ran before isB
}

detour over, back to the answer. )

So your understanding of the modifier is correct. Your understanding of what your code does, however, isnt. Here, assuming i > 1 when you call decrement, the beginning of the modifier will be ran, so locked will be set to true, then x will decrement, then the if() condition will evaluate to true ( i is greater than 1) which will call the function again, run the modifier code again, and the require statement require(!locked) will evaluate to false since the rest of the modifier that sets locked back to false hasnt run yet, and the call will revert.

1
  • thank you for correcting me! now I got it!
    – Simon Zhao
    Commented Dec 7, 2022 at 6:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.