Skip to content

Incorrect success value returned in vyper

High severity GitHub Reviewed Published Apr 24, 2023 in vyperlang/vyper • Updated Nov 10, 2023

Package

pip vyper (pip)

Affected versions

>= 0.3.1, < 0.3.8

Patched versions

0.3.8

Description

Background

During the audit of Lido's Gate Seals code statemind team identified a weird behavior of the code that uses raw_call: https://github.com/lidofinance/gate-seals/blob/051593e74df01a4131c485b4fda52e691cd4b7d8/contracts/GateSeal.vy#L164 .

Construction like this:

success = raw_call(
    sealable,
    _abi_encode(SEAL_DURATION_SECONDS, method_id=method_id("pauseFor(uint256)")),
    revert_on_failure=False
)

was not fully documented: https://docs.vyperlang.org/en/v0.3.7/built-in-functions.html#raw_call .

The documentation says that: if max_outsize=0 it should return nothing and then it says that if revert_on_failure=False it should return a success flag in the tuple of response, but what if max_outsize=0 and revert_on_failure=False.

image

So the team started researching what exactly happened in that case, after some research we found that the Vyper compiler generates the wrong bytecode in that case, it generates the sequence:

CALL // call
MLOAD // MLOAD is wrong since the CALL result is already stored in the stack

Impact

Example of buggy code:

@external
def returnSome(calling: address, a: uint256) -> bool:
    success: bool = false
    success = raw_call(
        calling,
        _abi_encode(a, method_id=method_id("a(uint256)")),
        revert_on_failure=False
        )

any contract that uses the raw_call with revert_on_failure=False and max_outsize=0 receives the wrong response from raw_call. Depending on the memory garbage, the result can be either True or False.

Patches

Fix by @charles-cooper vyperlang/vyper@851f7a1

Workarounds

The simple workaround is always to put max_outsize>0.
Workaround example https://github.com/lidofinance/gate-seals/pull/5/files

References

Lido's fix: https://github.com/lidofinance/gate-seals/pull/5/files

References

@charles-cooper charles-cooper published to vyperlang/vyper Apr 24, 2023
Published by the National Vulnerability Database Apr 24, 2023
Published to the GitHub Advisory Database Apr 24, 2023
Reviewed Apr 24, 2023
Last updated Nov 10, 2023

Severity

High
7.5
/ 10

CVSS base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
None
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

Weaknesses

CVE ID

CVE-2023-30629

GHSA ID

GHSA-w9g2-3w7p-72g9

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.