Skip to content

feat(solidity-import): support calldata slices, Governor proposer description checks, bytes1..bytes31 locals/casts, and MemberAccess tuple assignments - #2503

Merged
Th0rgal merged 1 commit into
mainfrom
feat/solidity-import-slice-42
Oct 12, 2026
Merged

Th0rgal merged 1 commit into
mainfrom
feat/solidity-import-slice-42

Conversation

@Th0rgal

@Th0rgal Th0rgal commented Oct 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Support bytes calldata and msg.data / _msgData() slice expressions (data[start:end], data[start:], data[:end], data[:]) in .length, bytesN(slice), abi.decode(slice, (...)), and memory materialization (bytes(slice), keccak256(slice), abi.encode*, bytes.concat) with exact bounds guards (start <= end <= base.length).
  • Support OpenZeppelin Governor._isValidDescriptionForProposer: unaligned Yul byte-buffer tail mload(add(buf, sub(len, k))) (1 <= k <= 32), dynamic bytes / bytes(string) element reads b[i] (bytes1 with Panic(0x32) bounds check), and bounded tail-window for (uint256 i = bound - K; i < bound; ++i) loops (including early if (...) return ...; inside helpers).
  • Support narrow fixed-bytes (bytes1..bytes31) locals, helper parameters/returns, bytesN("...") string literal casts (N < 32), and bytes12 / bytes20 conversions (bytes12 <-> uint96 / bytes32, bytes20 <-> uint160 / address / bytes32, ERC2771Context._msgSender()).
  • Support MemberAccess components in tuple assignments ((_roles[roleId].grantDelay, effect) = _roles[roleId].grantDelay.withUpdate(...) in AccessManager).
  • Add GovernorSliceProposerDelaySequence differential test fixture, rejection controls, and 4 mutation anchors.

…cription checks, bytes1..bytes31 locals/casts, and MemberAccess tuple assignments
@Th0rgal
Th0rgal merged commit 10f697b into main Oct 12, 2026
@Th0rgal
Th0rgal deleted the feat/solidity-import-slice-42 branch October 12, 2026 00:14
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T00:22:24.532281Z f13260a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: f13260a576

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +6083 to +6084
if let some (slicePre, offsetExpr, lenExpr, _) ← lowerCalldataSlice? inner then
return (slicePre, true, offsetExpr, lenExpr)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stitch selector-adjacent words before ABI decoding

When the source is a msg.data or _msgData() slice starting below byte 4, discarding isMsgData here sends the decoder through a plain calldataload(offset). The model's calldataloadWord returns only the selector at offset 0 and zero at offsets 1–3 (Verity/Core/Model/Denote.lean:140-143), so inputs such as abi.decode(msg.data[0:32], (bytes32)) omit the adjacent argument bytes and diverge from Solidity. Use the same selector/payload stitching already applied by lowerBytesToFixedBytes and lowerEncodedBytes, or reject these slice offsets.

Useful? React with 👍 / 👎.

Comment on lines +2689 to +2690
let pre := buf.pre ++ lhsVal.pre ++ #[
.letVar addrVar (.add buf.pointer (.sub lhsVal.expr (.literal (32 + k)))),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the synthetic length header in tail loads

For headerless buffers produced by expressions such as abi.encodePacked, this address translation is only equivalent while lhs >= 32 + k; otherwise the original Yul load reaches the dynamic-bytes length header, but the imported program reads unrelated memory before buf.pointer. For example, a one-byte buf and mload(add(buf, sub(mload(buf), 1))) returns the length word 1 in Solidity, whereas this lowers to mload(buf.pointer - 32) without ever storing that header. Either synthesize the length header or fail closed unless the address is guaranteed to remain in the payload.

Useful? React with 👍 / 👎.

Comment on lines +3676 to +3677
let env ← get
pure (env.stringBuffers.contains id.toNat || env.calldataBytes.contains id.toNat)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Admit byteBuffers when indexing bytes locals

A direct bytes memory local initialized from abi.encode, abi.encodePacked, or another supported byte expression is registered in env.byteBuffers, but this predicate only recognizes stringBuffers and calldataBytes. Consequently, an ordinary b[i] on such a local skips the new byte-index lowering and fails in lowerRef with the encoded-byte-local restriction, despite this change advertising dynamic bytes element reads. Include env.byteBuffers.contains id.toNat in the recognized identifier cases.

Useful? React with 👍 / 👎.

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.

1 participant