[RLH-10] Cut the README's copy of the abi.encode argument - #113
Merged
Merged
Conversation
The library title block in src/lib/LibHashNoAlloc.sol and the README carried the same argument against keccak256(abi.encode(...)), and they drifted: #90 corrected four claims on the NatSpec side that the README side never got. NatSpec is the copy a consumer reads at their pinned revision, so it is the copy that stays. The README loses the packed-collision example, the abi.encode fix with its decodability and cross-type claims, the encoding-overhead argument, the "1-10k+ gas" claim #90 had already corrected on the other side, the scratch-space mechanism and the induction-parity closer, and points at the library source instead. Its pattern walkthrough, worked examples, security induction, cross-type collision list and install section have no NatSpec counterpart and are untouched. Closes #50 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V8ViHcKLVk2YoS2joH4HdN
|
Warning Review limit reachedNext included review available in 31 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #50 (RLH-10).
#50 says the library title block and the README are two hand-maintained copies
of the same argument, and that they have already drifted (#90 landed four
corrections to the NatSpec side that the README side did not have). #79 answered
it by cutting the NatSpec and was closed unmerged: a
///block cannot point atthe README, because NatSpec is what renders in tooling and what a consumer reads
at the call site. This answers it the other way round. The NatSpec is the single
statement of the argument; the README loses its copy and points at
src/lib/LibHashNoAlloc.solinstead of restating it.README.mdonly. Nothing insrc/ortest/is touched.What was cut, and where it already lives
Line numbers are
main: README atf2a9f5f,src/lib/LibHashNoAlloc.solat thesame commit.
abi.encodePackedconcatenates,"abc"+"def"/"ab"+"cdef"pack alike, packed is safe only for fixed-length dataabi.encodefix,3"abc"+3"def"/2"ab"+4"cdef", head/tail offsets, the abi-spec URLuint256; the canonical encoding of one type tuple is decodable, so injective on itkeccak256allocates nothing; the scratch space it hashes throughabi.encode's decodability, reached without producing the encodingL222-224 is the stale side of a fact #90 corrected: the NatSpec's "easily 1k+
gas for simple structs" became measured figures ("several hundred ... even when
those fields are empty, and over 1k once they hold a handful of words"), and the
README's vaguer "easily 1-10k+ gas" was never brought along. It is deleted
rather than carried forward.
What was judged unique and kept
Nothing was cut that the NatSpec does not already state, and no prose was moved
into NatSpec to justify a cut.
Foostruct, thepointer-word rules, hashing contiguous words / word lists / byte strings, the
A-E pointer walkthrough, the fold and its measured gas fractions, the nil hash
prefix.
domain, one type" restriction, and the cross-type collision list under "Across
types nothing is unambiguous" - all of which the NatSpec defers to rather than
duplicates ("the notes on each function below list what collides").
NatSpec counterpart.
sections.
sentence that the cost is fundamental to encoding rather than Solidity's
fault, the bolded general claim about no-encode implementations with its
SSTORE2 /
LibDataContractmeasurement, and the note that Solidity gives nokeccak256for non-bytestypes. None of these has a NatSpec counterpart.## Problemopening sentence and the compiler transcript under it. Thesentence overlaps src L14-17, but a section headed "Problem" has to name its
subject for the transcript and the two questions to hang off; naming the
subject is not the argument.
@devon theHASH_NILconstant,not the title block, and the README's own fold description needs the seed
defined where it is defined.
Three passages in the title block have no README counterpart and so had nothing
to cut against: the internal-call overhead note (src L58-62), the
Headerexample (src L64-88, a different struct from the README's
Fooand making adifferent point), and the caller memory-safety paragraph (src L90-93).
One judgment call worth naming
L174-179 carried a concrete counterexample -
abi.encodeofuint8(1),uint256(1),trueandaddress(1)are the same 32 bytes - that #90 verifiedwith
cast abi-encode. The claim it illustrates is in the NatSpec at srcL23-24; the illustration is not. It went with the argument it illustrates rather
than being kept as a lone fragment of that argument in the README, and it is not
moved into the NatSpec. Flagging it because it is the only concrete thing that
went.
QA
README.mdonly, which nothingcompiles, imports or reads at runtime, so no observable value can differ
between base and branch. Inertness shown rather than asserted:
git diff --name-only mainis exactlyREADME.md, and the suite is 77passed / 0 failed / 0 skipped across 9 suites on
mainand identical on thisbranch.
mutate. The mutation-equivalent for a deleted passage is that the passage was
not the only statement of what it said: each row of the table above was
checked by reading the NatSpec line independently and confirming it states the
same thing. No surviving line depends on a cut passage for its meaning either
abi.encodePackedmentions in README are the## Problemframing (L18), the compiler transcript (L28), the new pointer (L156) and the
length-prefix remark at L496, which the surviving EIP712 material at L316
already grounds; the surviving "scratch space" uses at L370-383 are introduced
by the pointer at L172, which precedes them; and nothing in
src/ortest/cites README prose at all.
src/lib/LibHashNoAlloc.solitself, read line by line against theREADME passages, not the audit text in the issue - the issue argues the cut in
the other direction and its line numbers predate the
src/lib/move, so itsevidence was re-derived here against current
main.(b) the README pointing at the library source instead of restating it, (c)
nothing cut that has no NatSpec counterpart and no prose moved into NatSpec,
(d) no stale README claim carried into the survivor. Covered: (a) the eight
passages in the table, 62 lines deleted; (b) three pointers - one in the intro,
one replacing the body of "Collisions with ABI encoding", one in "Gas cost of
encoding" - each naming the topics the title block carries rather than
restating its conclusions; (c) the kept list above, with each keep's reason,
and
src/is untouched; (d) L222-224 deleted as the stale side of [RLH-09] Correct four claims in the LibHashNoAlloc title block #90'scorrection, and every other cut passage's surviving copy is the post-[RLH-09] Correct four claims in the LibHashNoAlloc title block #90 text.
Suite: 77 passed / 0 failed / 0 skipped across 9 suites, before and after.
forge fmt --checkclean.pre-commit run --all-filespasses and rewritesnothing, run again after the edit to confirm the tree is stable.
🤖 Generated with Claude Code
https://claude.ai/code/session_01V8ViHcKLVk2YoS2joH4HdN