{"id":"CVE-2020-37289","kind":"vulnerability","aliases":["CVE-2020-37289"],"related":[],"title":"Vyper: uint8 return values from interfaces skip bounds checks","description":"Vyper before 0.3.1 lacks a uint8 type, allowing interface return values declared as uint8, such as ERC20.decimals(), to be stored in uint256 variables without bounds checking. Malicious contracts can return values greater than 255 to manipulate or bypass contract logic that relies on these values.","summary":"Vyper before 0.3.1 has no uint8 type, so interface functions declared to return uint8, such as ERC20.decimals(), are stored in uint256 without bounds checking. A malicious contract can return values above 255 and so manipulate or bypass logic that trusts those values.","severity":"medium","cvss":6.3,"epss":0.00261,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["ethereum","package","smart-contracts","vyper"],"not_affected_if":["no-external-uint8-calls","vyper-0.3.1-or-later"],"how_to_check":"- Run `vyper --version` in each project that compiles Vyper contracts and check whether it is below `0.3.1`.\n- Search the contracts for interfaces that declare `uint8` return values and that read from external or untrusted contracts.","fix":"- Upgrade Vyper to `0.3.1` or later and recompile.\n- Validate values returned from external contracts (for example, check that decimals are at most 255) before trusting them.","status":"open","published_at":"2026-10-21T01:17:18+00:00","first_seen_at":"2026-10-23T21:57:27+00:00","triaged_at":"2026-10-25T04:01:28+00:00","updated_at":"2026-10-25T04:01:28+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-10-25T04:01:28Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade Vyper to `0.3.1` or later and recompile.\n- Validate values returned from external contracts (for example, check that decimals are at most 255) before trusting them.","reach":"internet","title":"Vyper: uint8 return values from interfaces skip bounds checks","impact":"medium","summary":"Vyper before 0.3.1 has no uint8 type, so interface functions declared to return uint8, such as ERC20.decimals(), are stored in uint256 without bounds checking. A malicious contract can return values above 255 and so manipulate or bypass logic that trusts those values.","category":"package","nicknames":[],"who_cares":["vyper","smart-contracts","ethereum"],"confidence":0.7,"needs_auth":"no","worst_case":"A malicious contract returns out-of-range values that bypass contract logic","analyst_note":"","how_to_check":"- Run `vyper --version` in each project that compiles Vyper contracts and check whether it is below `0.3.1`.\n- Search the contracts for interfaces that declare `uint8` return values and that read from external or untrusted contracts.","needs_analyst":false,"not_affected_if":["vyper-0.3.1-or-later","no-external-uint8-calls"],"who_is_affected":"Teams that compile Vyper contracts older than 0.3.1 and that call external contracts through interfaces declaring uint8 returns. Exposure depends on whether the contract trusts a value an untrusted contract can return. Projects on 0.3.1 or later, or with no external uint8 calls, can skip it.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000624,"input_tokens":3371,"output_tokens":573,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-2020':11A,14A '-37289':12A,15A '0.3.1':24B,66C '255':53B,97C 'allow':71C 'bound':8A,44B,88C 'bypass':58B,101C 'check':9A,45B,89C 'contract':20B,48B,91C,102C 'cve':10A,13A 'declar':32B,75C 'erc20.decimals':38B,80C 'ethereum':16B 'function':31B 'greater':95C 'interfac':6A,30B,72C 'lack':67C 'logic':59B,103C 'malici':47B,90C 'manipul':56B,99C 'packag':17B 'reli':105C 'return':3A,34B,50B,73C,93C 'skip':7A 'smart':19B 'smart-contract':18B 'store':40B,83C 'trust':61B 'type':28B,70C 'uint256':42B,85C 'uint8':2A,27B,35B,69C,77C 'valu':4A,51B,63B,74C,94C,108C 'variabl':86C 'vyper':1A,21B,22B,64C 'without':43B,87C","nicknames":[],"mitigations":[],"who_affected":"Teams that compile Vyper contracts older than 0.3.1 and that call external contracts through interfaces declaring uint8 returns. Exposure depends on whether the contract trusts a value an untrusted contract can return. Projects on 0.3.1 or later, or with no external uint8 calls, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-21T01:17:18+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2020-37289","url":"https://nvd.nist.gov/vuln/detail/CVE-2020-37289","severity":null,"published_at":"2026-10-21T01:17:18+00:00","modified_at":"2026-10-22T17:00:33+00:00","first_seen_at":"2026-10-23T21:57:27+00:00","fetched_at":"2026-10-23T22:29:01+00:00","note":null},{"source":"epss","external_id":"CVE-2020-37289","url":"https://api.first.org/data/v1/epss?cve=CVE-2020-37289","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-24T13:15:55+00:00","fetched_at":"2026-10-24T13:15:55+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}