{"schema":"threatline.record/2","record":{"id":"GHSA-fxg7-4wqg-c8gh","aliases":["GHSA-fxg7-4wqg-c8gh"],"summary":"`create_from_blueprint` offset validation bypass through unsigned wraparound","details":"## Summary\r\n\r\nVyper's `create_from_blueprint` can deploy a contract with empty runtime bytecode instead of reverting when supplied with an invalid `code_offset`. Contracts that allow attackers to control this parameter are affected.\r\n\r\n## Details\r\n\r\nThe builtin computes the remaining blueprint code size using EVM subtraction, then validates the result with a signed comparison:\r\n\r\n```python\r\ncodesize = [\"sub\", [\"extcodesize\", target], code_offset]\r\ncheck_codesize = [\"assert\", [\"sgt\", codesize, 0]]\r\n```\r\n\r\nBecause `code_offset` is a `uint256`, subtraction can wrap modulo `2^256` and produce a small positive result that passes the check.\r\n\r\nFor example, given a blueprint with 200 bytes of code:\r\n\r\n```text\r\ncode_offset = 2^256 - 1\r\ncodesize    = 200 - (2^256 - 1) mod 2^256 = 201\r\nsgt(201, 0) = true\r\n```\r\n\r\n`EXTCODECOPY` then reads beyond the blueprint's code and fills the destination with zeros. The resulting initcode begins with `STOP`, so contract creation succeeds and returns an address with no runtime code. The oversized source offset does not itself cause excessive gas consumption.\r\n\r\n## Impact\r\n\r\nAn attacker who controls `code_offset` can cause a factory to deploy empty contracts instead of the intended blueprint instances. Depending on the application, this can disrupt initialization, violate assumptions about deployed contracts, or leave ETH and tokens sent to those addresses inaccessible.\r\n\r\nThe common pattern using a fixed, valid offset such as `code_offset=3` is unaffected by this bypass.\r\n\r\n## Remediation\r\n\r\nValidate **`code_offset < extcodesize(target)` using an unsigned comparison before subtraction**. Checking only the wrapped result, even with an unsigned comparison, does not prevent the bypass.\r\n\r\nAs a workaround, use a fixed, valid offset or explicitly enforce this bound before calling `create_from_blueprint`.\r\n","categories":["Unclassified"],"product":"vyper","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/vyperlang/vyper/security/advisories/GHSA-fxg7-4wqg-c8gh","source_modified_at":"2026-10-06T08:45:22Z","fetched_at":"2026-10-23T20:39:26.410340Z","package":{"ecosystem":"pip","name":"vyper"},"range":">= 0.3.4"}],"fixed_versions":[],"cvss":null,"severity":"Low","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-06T08:45:22Z","modified_at":"2026-10-06T08:45:22Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/vyperlang/vyper/security/advisories/GHSA-fxg7-4wqg-c8gh","fetched_at":"2026-10-23T20:39:26.410340Z","source_modified_at":"2026-10-06T08:45:22Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-06T08:45:22Z","content_hash":"0dbf6568776d0c14faadf2cef5c297791f952bfc31fa7bbad2a2cef45d0a5dfe"}}
