CVE-2023-30629
📋 TL;DR
The Vyper compiler generates incorrect bytecode for contracts using raw_call with revert_on_failure=False and max_outsize=0, causing unpredictable boolean return values. This affects all smart contracts compiled with Vyper versions 0.3.1 through 0.3.7 that use this specific raw_call configuration.
💻 Affected Systems
- Vyper compiler
📦 What is this software?
Vyper by Vyperlang
⚠️ Risk & Real-World Impact
Worst Case
Smart contracts could execute unintended logic based on incorrect boolean values from raw_call, potentially leading to unauthorized fund transfers, contract state corruption, or denial of service.
Likely Case
Contracts may behave unpredictably when processing raw_call results, causing transaction failures or incorrect state changes depending on memory garbage values.
If Mitigated
With proper input validation and workarounds, contracts can avoid the vulnerable configuration and maintain expected behavior.
🎯 Exploit Status
Exploitation depends on contract logic that relies on raw_call return values. The vulnerability is deterministic based on compiler behavior.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: 0.3.8
Vendor Advisory: https://github.com/vyperlang/vyper/security/advisories/GHSA-w9g2-3w7p-72g9
Restart Required: No
Instructions:
1. Upgrade Vyper compiler to version 0.3.8 or later. 2. Recompile all affected smart contracts with the patched compiler. 3. Redeploy recompiled contracts to blockchain networks.
🔧 Temporary Workarounds
Modify raw_call parameters
allChange max_outsize parameter to be greater than 0 in all raw_call invocations with revert_on_failure=False
Modify contract source: raw_call(target, data, gas=gas, revert_on_failure=False, max_outsize=1)
🧯 If You Can't Patch
- Audit all contracts for raw_call usage with revert_on_failure=False and max_outsize=0
- Implement additional validation logic to handle unexpected boolean return values from raw_call
🔍 How to Verify
Check if Vulnerable:
Check Vyper compiler version with 'vyper --version'. If version is between 0.3.1 and 0.3.7 inclusive, and contracts use raw_call with revert_on_failure=False and max_outsize=0, they are vulnerable.
Check Version:
vyper --version
Verify Fix Applied:
After upgrading to 0.3.8+, recompile contracts and verify bytecode differs from previous compilation. Test raw_call behavior with the problematic parameter combination.
📡 Detection & Monitoring
Log Indicators:
- Unexpected contract behavior when raw_call returns True/False
- Transaction reversals related to external call processing
Network Indicators:
- Unusual contract interactions involving raw_call patterns
- Failed transactions to contracts using vulnerable Vyper versions
SIEM Query:
Not applicable for blockchain environments
🔗 References
- https://docs.vyperlang.org/en/v0.3.7/built-in-functions.html#raw_call
- https://github.com/lidofinance/gate-seals/blob/051593e74df01a4131c485b4fda52e691cd4b7d8/contracts/GateSeal.vy#L164
- https://github.com/lidofinance/gate-seals/pull/5/files
- https://github.com/vyperlang/vyper/commit/851f7a1b3aa2a36fd041e3d0ed38f9355a58c8ae
- https://github.com/vyperlang/vyper/security/advisories/GHSA-w9g2-3w7p-72g9
- https://docs.vyperlang.org/en/v0.3.7/built-in-functions.html#raw_call
- https://github.com/lidofinance/gate-seals/blob/051593e74df01a4131c485b4fda52e691cd4b7d8/contracts/GateSeal.vy#L164
- https://github.com/lidofinance/gate-seals/pull/5/files
- https://github.com/vyperlang/vyper/commit/851f7a1b3aa2a36fd041e3d0ed38f9355a58c8ae
- https://github.com/vyperlang/vyper/security/advisories/GHSA-w9g2-3w7p-72g9