Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State can be modified in a range expression using pop #3172

Open
trocher opened this issue Dec 6, 2022 · 0 comments · May be fixed by #3188, #3884 or #3546
Open

State can be modified in a range expression using pop #3172

trocher opened this issue Dec 6, 2022 · 0 comments · May be fixed by #3188, #3884 or #3546
Labels
bug - type 1 bug which results in incorrect codegen bug - typechecker issue with typechecker

Comments

@trocher
Copy link
Contributor

trocher commented Dec 6, 2022

Version Information

  • vyper Version (output of vyper --version): 0.3.8+commit.046ea166
  • OS: OSX
  • Python Version (output of python --version): 3.8.0

What's your issue about?

Range expressions, when formed as range(x, x + CONSTANT), prevent x to be a call to state modifying functions. For example, the following contract would compile only if bar was a view or a pure function. Under its current form, the compiler raise a StateAccessViolation with the following reason: May not call state modifying function 'bar' within a range.

@internal
def bar()->uint256:
    return 0

@external
def test()-> (DynArray[uint256,6]):
    b:DynArray[uint256,6] = []
    for i in range(self.bar(),self.bar()+2):
        b.append(i)
    return b

However, it is possible to call the DynArray's pop function inside the range expression. If the dynamic array from which a value is popped is a state variable, the range expression is effectively calling a state modifying function. Note that only one value is popped.
For example, this contract compiles and a call to test output ([0,1],[1]), meaning that arr has been modified by the range by popping one value.

arr:DynArray[uint256,10]
@external
def test()-> (DynArray[uint256,6],DynArray[uint256,10]):
    b:DynArray[uint256,6] = []
    self.arr = [1,0]
    for i in range(self.arr.pop(),self.arr.pop()+2):
        b.append(i)
    return b,self.arr # return ([0, 1], [1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug - type 1 bug which results in incorrect codegen bug - typechecker issue with typechecker
Projects
None yet
3 participants