Skip to content

fix[venom]: type state variable reads with the declared type - #5239

Merged
harkal merged 7 commits into
vyperlang:masterfrom
harkal:fix/venom/storage-read-declared-type
Sep 8, 2026
Merged

harkal merged 7 commits into
vyperlang:masterfrom
harkal:fix/venom/storage-read-declared-type

Conversation

@harkal

@harkal harkal commented Sep 4, 2026 •

Copy link
Copy Markdown
Collaborator

What I did

Fix a venom-only miscompile when a storage, transient or immutable variable is
read into a wider type, e.g. ys: DynArray[Bytes[512], 5] = self.stored with
stored: DynArray[Bytes[10], 5]. Same bug family as #5236.

The semantic pass stamps the self.x / lib.X node with the expected
(widened) type. codegen_venom used that type to describe the borrowed pointer
to the state variable, but the data has the declared type's layout. Two things
went wrong:

  • slot over-read: load_storage_to_memory sized the copy loop from the wide
    type (86 slots for DynArray[Bytes[512], 5] vs the declared 11), reading
    slots that belong to neighbouring variables;
  • layout skew: the copied words were then walked with the wide element stride
    (544 bytes vs 64), so every element after the first was garbage.

For [b'a', b'0123456789', b''] this returned [b'a', b'', b'']; other shapes
halted out of gas. Immutables had the same defect via
load_immutable_to_memory. Legacy codegen is unaffec
these IRnodes with varinfo.typ.

How I did it

Type the pointer returned by lower_Attribute (state variable reads) and
lower_Name (immutable reads) with the variable's de
node._metadata["type"]. The existing typed copies on the consumer side
(store_memory(..., src_typ=...), `_store_complex_ty
return encoding, call args) then widen element-wise. No new copy machinery.

Not covered here: for x: <wide> in self.stored copies each element linearly
in _lower_iter_loop and has the same class of bug f
widenings. That is a separate code path and will be a separate PR.

How to verify it

Commit message

state variable reads in codegen_venom wrapped the storage/transient/immutable
pointer with the node's expected type, which can be w
declared type. the storage-to-memory copy then read storage_size_in_words
of the wide type (slots past the variable) and the re
wide element stride, corrupting every element after the first.

type the pointer with varinfo.typ; the existing typed stores widen the
value at the consumer.

Description for the changelog

Cute Animal Picture

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Gas Changes

No changes detected.

Summary

  • Total tests measured: 560
  • Changed: 0
  • Regressions (gas up): 0
  • Improvements (gas down): 0
  • New tests: 0
  • Deleted tests: 0
  • Newly failing: 0
  • Newly passing: 0

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

📊 Bytecode Size Changes (venom)

No changes detected.

Full bytecode sizes

Contract legacy-O2 legacy-Os -O2 -O3 -Os
curvefi/legacy/CurveStableSwapMetaNG.vy 24952 23578 19847 19107 18571
curvefi/amm/stableswap/meta_implementation/meta_implementation_v_700.vy 23610 22805 19618 18650 18337
curvefi/amm/stableswap/implementation/implementation_v_700.vy 24962 23769 19237 18382 18038
curvefi/legacy/CurveStableSwapNG.vy 24473 23298 18802 18004 17659
curvefi/amm/tricryptoswap/implementation/implementation_v_200.vy 20724 19959 17250 16689 16325
curvefi/amm/twocryptoswap/implementation/implementation_v_210.vy 17634 16894 14958 14376 14027
yearnfi/VaultV3.vy 19972 19063 14749 13828 13279
curvefi/legacy/CurveCryptoSwap2.vy 18947 18382 14619 14129 13954
yearnfi/VaultV2.vy 16676 15763 13262 12470 12053
curvefi/amm/stableswap/factory/factory_v_100.vy 14558 13978 11864 10792 10892
curvefi/gauge/child_gauge/implementation/implementation_v_110.vy 12338 11561 9840 9213 8824
curvefi/amm/stableswap/views/views_v_120.vy 12784 12368 9705 9059 9294
curvefi/gauge/child_gauge/implementation/implementation_v_100.vy 12017 11249 9573 8953 8567
curvefi/amm/tricryptoswap/math/math_v_200.vy 11189 11126 9029 8144 8170
curvefi/legacy/CurveCryptoMathOptimized3.vy 11188 11125 9028 8144 8170
curvefi/gauge/child_gauge/implementation/implementation_v_020.vy 10665 9947 8685 8129 7743
curvefi/registries/metaregistry/metaregistry_v_110.vy 7590 6732 6491 5710 5603
curvefi/helpers/router/router_v_110.vy 6717 6717 6251 5733 6035
curvefi/amm/tricryptoswap/views/views_v_200.vy 7821 7776 6114 5899 6048
curvefi/helpers/stable_swap_meta_zap/stable_swap_meta_zap_v_100.vy 7302 7067 5878 5351 5611
curvefi/amm/twocryptoswap/views/views_v_200.vy 6991 6946 5685 5484 5619
curvefi/registries/metaregistry/registry_handlers/stableswap/handler_v_110.vy 6633 6259 5533 4695 5238
curvefi/amm/twocryptoswap/math/math_v_210.vy 6800 6800 5506 5012 5039
curvefi/amm/twocryptoswap/factory/factory_v_200.vy 5540 5252 4617 3917 4047
curvefi/amm/tricryptoswap/factory/factory_v_200.vy 5246 5021 4483 3890 4020
curvefi/gauge/child_gauge/factory/factory_v_201.vy 4844 4547 3901 3675 3511
curvefi/registries/metaregistry/registry_handlers/tricryptoswap/handler_v_110.vy 4241 3939 3718 3334 3429
curvefi/registries/metaregistry/registry_handlers/twocryptoswap/handler_v_110.vy 4186 3884 3675 3255 3333
curvefi/gauge/child_gauge/factory/factory_v_100.vy 4183 3914 3408 3144 2971
yearnfi/VaultFactory.vy 3765 3617 3031 2193 2494
curvefi/registries/address_provider/address_provider_v_201.vy 2973 2782 2617 2443 2357
curvefi/helpers/rate_provider/rate_provider_v_101.vy 3260 3260 2544 2272 2305
curvefi/amm/stableswap/math/math_v_100.vy 3067 3046 2457 2252 2309
curvefi/helpers/rate_provider/rate_provider_v_100.vy 2847 2841 2313 1994 2014
curvefi/helpers/deposit_and_stake_zap/deposit_and_stake_zap_v_100.vy 2322 2316 1782 1611 1670
curvefi/governance/relayer/taiko/relayer_v_001.vy 2068 2064 1730 1509 1557
curvefi/governance/relayer/polygon_cdk/relayer_v_101.vy 1556 1523 1530 1324 1347
curvefi/governance/relayer/arb_orbit/relayer_v_101.vy 1266 1262 1242 1066 1115
curvefi/governance/relayer/op_stack/relayer_v_101.vy 1186 1182 1183 1014 1056
curvefi/governance/relayer/not_rollup/relayer_v_100.vy 1168 1153 1174 1011 1037
curvefi/governance/vault/vault_v_100.vy 964 941 862 823 839
curvefi/governance/relayer/relayer_v_100.vy 496 496 593 490 503
curvefi/governance/agent/agent_v_100.vy 541 541 430 402 406
curvefi/governance/agent/agent_v_101.vy 541 541 430 402 406

@harkal
harkal marked this pull request as ready for review September 4, 2026 10:31

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a23d740576

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread vyper/codegen_venom/expr.py

@charles-cooper charles-cooper left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm it's a bit surprising that this changes behavior. @Sporarum can you take a look?

@harkal
harkal requested review from HodanPlodky and charles-cooper and removed request for Sporarum September 4, 2026 14:52

@Sporarum Sporarum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The one question I have, is why only those specific cases ?
I'm also having issues with ternary ifs, and I think the root cause is the same

@harkal
harkal merged commit a6b31a3 into vyperlang:master Sep 8, 2026
171 checks passed
@harkal
harkal deleted the fix/venom/storage-read-declared-type branch September 8, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants