Skip to content

First Immutable Variable Initialization

Moderate
hedgar2017 published GHSA-h8jv-969m-94r4 Oct 25, 2023

Package

zkvyper (Vyper)

Affected versions

<1.3.10

Patched versions

1.3.10

Description

Impact

The bug prevented the initialization of the first immutable variable for Vyper contracts meeting the criteria described below.

The problem arises when there is a String or Array with more 256-bit words allocated than initialized.
In the example below, there is a string with 64 bytes allocated, but only 4 (32) are written.

It results in the 2nd word’s index unset, that is effectively set to 0, so the first immutable value with the actual 0 index is overwritten in the ImmutableSimulator.

As the fix, our compiler will have to set all indexes in advance. The problem will go away, but it will get more expensive if the user allocates a lot of uninitialized space, e.g. String[4096].

Vyper source code example:

# @version 0.3.9

IMMUTABLE_1: public(immutable(bytes32))
IMMUTABLE_2: public(immutable(String[64]))

@external
def __init__():
    IMMUTABLE_1 = keccak256(_abi_encode(msg.sender))
    IMMUTABLE_2 = "Test"

Constructor return data:

0x32
0x04
0x00 IMMUTABLE_1
0x20 0x40
0x40 "Test"
0x00 0x00.       // The index must have been 0x60 here

Analysis has shown that no contracts were affected by the date of publishing this advisory.

Patches

Fixed in version 1.3.10.

Workarounds

Upgrading and redeploying affected contracts is the only way.

Severity

Moderate

CVE ID

CVE-2023-46232

Weaknesses

No CWEs

Credits