vyperlang / vyper

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

overriding allocator does not set global lock position causing crash in codegen #3996

Closed cyberthirst closed 2 months ago

cyberthirst commented 3 months ago

Version Information

OverridingStorageAllocator.set_storage_slots_with_overrides() iterates over the FunctionDef AST nodes of the top-level module to find non-reentrant functions. If one is found, the compiler reserves some slot according to what was provided in the JSON file of storage slots overrides and annotates the function type with the given reentrant slot. However, for the next functions, the compiler will not annotate the function type with any slot. The issue is later caught at the code generation phase, where the compiler will crash.

POC

For example, the following example would crash with AttributeError: 'ContractFunctionT' object has no attribute 'reentrancy_key_position'.

@nonreentrant
@external
def a():
    pass

@nonreentrant
@external
def b():
    pass

credits: @trocher

cyberthirst commented 3 months ago

the lock is shared for all funs, thus if we continue on line 167, we skip the setter on line 176: https://github.com/vyperlang/vyper/blob/097aecfe29e6c218d165d223f0272265cf6f5403/vyper/semantics/analysis/data_positions.py#L166-L176

cyberthirst commented 3 months ago

in 0.3.10, the setter was within the same block as continue https://github.com/vyperlang/vyper/blob/9136169468f317a53b4e7448389aa315f90b95ba/vyper/semantics/analysis/data_positions.py#L91-L94