vyperlang / vyper

Pythonic Smart Contract Language for the EVM
https://vyperlang.org
Other
4.81k stars 788 forks source link

Storage Variable of Type `ModuleT` and `InterfaceT` Not Prevented #4123

Open ritzdorf opened 3 months ago

ritzdorf commented 3 months ago

Version Information

Since ModuleT is a Vyper type, and since ModuleT._invalid_locations does not contain DataLocation.STORAGE, it is possible to use it as a type for a storage variable while this should not be possible.

The contract below will compile, and calling foo() will return (1,2).

# main.vy
import lib

initializes: lib

x:lib
y:lib

@external
def foo() -> (uint256, uint256):
    return (self.x.bar(), self.y.bar())
# lib.vy
a:uint256

@internal
def bar()->uint256:
    self.a += 1
    return self.a

Note that a similar behavior can be observed for InterfaceT.

charles-cooper commented 3 months ago

i think the InterfaceT behavior is on purpose (e.g. you have have a variable of type IERC20), the ModuleT behavior is kind of odd though.

charles-cooper commented 1 month ago

should be fixed in https://github.com/vyperlang/vyper/pull/4088