Vyper: Return inside for loop more than 1 level deep
# VVE-2020-0002 Earlier today, we received a responsible disclosure of a potential issue from @michwill (developer of @curvefi) for Vyper users who use return statements inside for loops of nested internal calls. Returning inside a for loop causes an invalid jump dest, reverting the transaction unnecessarily. MWE: ```python @internal def _baz(): for i in range(1): return # Stack underflow happens here @internal def _bar(): self._baz() @external def foo(): self._bar() ``` ### Impact Impact is minor, it is unlikely a user would encounter this problem unless they were working with nested calls, and return statements inside calls. Even in that scenario, you would encounter a revert which should be noticeable with adequate testing. In limited circumstances, this could cause a DoS attack for public contracts under certain conditions. ### Patches Fixed in https://github.com/vyperlang/vyper/pull/2110. Please upgrade to [Vyper 0.2.3](https://pypi.org/project/vyper/) ### Workarounds Not returning inside a for loop nested 2+ internal calls deep works as is: ```python @internal def _baz(): for i in range(1): pass return # This works fine @internal def _bar(): self._baz() @external def foo(): self._bar() ``` ### For more information If you have any questions or comments about this advisory: * Chat with us in [our gitter ](https://gitter.im/vyperlang/community) * Open an issue in [https://github.com/vyperlang/vyper](https://github.com/vyperlang/vyper) * Email us at [security@vyperlang.org]
- Products
- vyper
- Affected versions
- 0.1.0b10, 0.1.0b11, 0.1.0b12, 0.1.0b13, 0.1.0b14, 0.1.0b15, 0.1.0b16, 0.1.0b17, 0.2.1, 0.2.2
- Fixed versions
- 0.2.3
- CVEs
- CVE-2020-37288
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 1 Nov 2026, 03:39 UTC · Revision 1
Source evidence
Vyper: Return inside for loop more than 1 level deep
core-osv · Original sourcePublished 6 Oct 2026, 15:20 UTC
# VVE-2020-0002 Earlier today, we received a responsible disclosure of a potential issue from @michwill (developer of @curvefi) for Vyper users who use return statements inside for loops of nested internal calls. Returning inside a for loop causes an invalid jump dest, reverting the transaction unnecessarily. MWE: ```python @internal def _baz(): for i in range(1): return # Stack underflow happens here @internal def _bar(): self._baz() @external def foo(): self._bar() ``` ### Impact Impact is minor, it is unlikely a user would encounter this problem unless they were working with nested calls, and return statements inside calls. Even in that scenario, you would encounter a revert which should be noticeable with adequate testing. In limited circumstances, this could cause a DoS attack for public contracts under certain conditions. ### Patches Fixed in https://github.com/vyperlang/vyper/pull/2110. Please upgrade to [Vyper 0.2.3](https://pypi.org/project/vyper/) ### Workarounds Not returning inside a for loop nested 2+ internal calls deep works as is: ```python @internal def _baz(): for i in range(1): pass return # This works fine @internal def _bar(): self._baz() @external def foo(): self._bar() ``` ### For more information If you have any questions or comments about this advisory: * Chat with us in [our gitter ](https://gitter.im/vyperlang/community) * Open an issue in [https://github.com/vyperlang/vyper](https://github.com/vyperlang/vyper) * Email us at [security@vyperlang.org]
osv:GHSA-vg88-3v92-rjx2
vyper
Fixed versions: 0.2.3
Complete source record
{
"id": "2f3ab9de0e56727886ac327778321e62c563a4c11cdbf971d3019b34b796cf4b",
"url": "https://osv.dev/vulnerability/GHSA-vg88-3v92-rjx2",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "Vyper: Return inside for loop more than 1 level deep",
"summary": "# VVE-2020-0002 Earlier today, we received a responsible disclosure of a potential issue from @michwill (developer of @curvefi) for Vyper users who use return statements inside for loops of nested internal calls. Returning inside a for loop causes an invalid jump dest, reverting the transaction unnecessarily. MWE: ```python @internal def _baz(): for i in range(1): return # Stack underflow happens here @internal def _bar(): self._baz() @external def foo(): self._bar() ``` ### Impact Impact is minor, it is unlikely a user would encounter this problem unless they were working with nested calls, and return statements inside calls. Even in that scenario, you would encounter a revert which should be noticeable with adequate testing. In limited circumstances, this could cause a DoS attack for public contracts under certain conditions. ### Patches Fixed in https://github.com/vyperlang/vyper/pull/2110. Please upgrade to [Vyper 0.2.3](https://pypi.org/project/vyper/) ### Workarounds Not returning inside a for loop nested 2+ internal calls deep works as is: ```python @internal def _baz(): for i in range(1): pass return # This works fine @internal def _bar(): self._baz() @external def foo(): self._bar() ``` ### For more information If you have any questions or comments about this advisory: * Chat with us in [our gitter ](https://gitter.im/vyperlang/community) * Open an issue in [https://github.com/vyperlang/vyper](https://github.com/vyperlang/vyper) * Email us at [security@vyperlang.org]",
"evidence": "osv:GHSA-vg88-3v92-rjx2",
"products": [
{
"name": {
"value": "vyper",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "0.2.3",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": [
{
"value": "0.1.0b10",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b11",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b12",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b13",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b14",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b15",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b16",
"evidence": "/affected/0/versions"
},
{
"value": "0.1.0b17",
"evidence": "/affected/0/versions"
},
{
"value": "0.2.1",
"evidence": "/affected/0/versions"
},
{
"value": "0.2.2",
"evidence": "/affected/0/versions"
}
]
}
],
"severity": "medium",
"structured": {
"id": "GHSA-vg88-3v92-rjx2",
"aliases": [
"CVE-2020-37288",
"GHSA-vg88-3v92-rjx2"
],
"metrics": [
{
"type": "CVSS_V4",
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N"
}
],
"affected": [
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0.1.0b10"
},
{
"fixed": "0.2.3"
}
]
}
],
"package": {
"name": "vyper",
"purl": "pkg:pypi/vyper",
"ecosystem": "PyPI"
},
"versions": [
"0.1.0b10",
"0.1.0b11",
"0.1.0b12",
"0.1.0b13",
"0.1.0b14",
"0.1.0b15",
"0.1.0b16",
"0.1.0b17",
"0.2.1",
"0.2.2"
],
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-vg88-3v92-rjx2/GHSA-vg88-3v92-rjx2.json"
}
}
],
"modified": "2026-10-24T02:56:09.007506586Z",
"provider": "osv",
"references": [
"https://github.com/vyperlang/vyper/security/advisories/GHSA-vg88-3v92-rjx2",
"https://github.com/vyperlang/vyper/pull/2110",
"https://github.com/vyperlang/vyper/commit/a1d92e5eb968a34a23850359656aee23334adb90",
"https://github.com/vyperlang/vyper",
"https://github.com/vyperlang/vyper/releases/tag/v0.2.3"
],
"provider_metadata": {
"cwe_ids": [
"CWE-691"
],
"severity": "MODERATE",
"github_reviewed": true,
"nvd_published_at": null,
"github_reviewed_at": "2026-10-06T15:20:10Z"
}
},
"related_cves": [
{
"value": "CVE-2020-37288",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/severity/0/score"
},
"source_id": "core-osv",
"document_id": 428179,
"published_at": "2026-10-06T15:20:10+00:00"
}