Repository navigation
Context words read their true value per entrypoint or revert (M02) - #2921
thedavidmeister wants to merge 5 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Walkthrough
Merge Risk:
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dex sub parser is for the dex. The post-arb task keeps main's context: balances in column 1, full base column. CALLING_CONTEXT_COLUMNS drops to 6; signers and signed context derive from CONTEXT_COLUMNS (7, 8+). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔇 Additional comments: 15
src/lib/LibRaindex.sol: 1
22-31: LGTM!Also applies to: 33-61, 99-107, 110-116
test/util/fixture/LibRaindexSubParserContextFixture.sol: 1
15-15: LGTM!Also applies to: 44-48, 52-52, 61-61
src/concrete/raindex/RaindexV6.sol: 1
55-56: LGTM!Also applies to: 179-187, 218-233, 316-319, 725-728
test/concrete/raindex/RaindexV6.contextWordEntrypoints.t.sol: 1
1-307: LGTM!test/util/lib/LibTestContextWords.sol: 1
1-41: LGTM!crates/test_fixtures/abis/RaindexV6.json: 1
2365-2365: LGTM!crates/test_fixtures/abis/RaindexV6SubParser.json: 1
245-245: LGTM!src/concrete/parser/RaindexV6SubParser.sol: 1
17-18: LGTM!Also applies to: 35-35, 51-53, 112-113, 121-122, 171-171, 183-183, 205-206, 217-218, 280-280, 287-287, 297-297, 305-305
src/lib/LibRaindexSubParser.sol: 2
13-17: LGTM!Also applies to: 91-92, 117-145, 326-326, 336-336, 346-346, 356-356, 366-366, 376-376, 386-386, 396-396, 406-406, 416-416, 426-427, 438-438, 451-456, 476-482, 628-628, 671-671
319-319:Trivial · Maintainability & Code Quality · Low value
⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.Update the stale NatSpec on the deposit and withdraw sub-parser functions.
The
@devcomments onsubParserDepositTokenthroughsubParserWithdrawTokenDecimals(Lines 319 to 427) still say each word maps to the "calling context column". This change moved those words toCONTEXT_DEPOSIT_COLUMNandCONTEXT_WITHDRAW_COLUMN. The newsubParserDepositorandsubParserWithdrawercomments are correct. Change the old comments to "deposit column" and "withdraw column".test/concrete/parser/RaindexV6SubParser.operandHandlersWiring.t.sol: 1
14-18: LGTM!Also applies to: 28-28, 37-48, 70-71, 75-75, 81-82, 95-96, 99-99
test/concrete/parser/RaindexV6SubParser.routing.t.sol: 1
63-63: LGTM!Also applies to: 77-80, 136-140, 143-143, 147-147, 151-151, 155-155, 158-162, 165-165, 169-169, 173-173, 177-177, 181-181, 186-186, 189-191, 195-195, 197-205
test/concrete/parser/RaindexV6SubParser.routingTokenDecimalsAndMasks.t.sol: 1
12-14: LGTM!Also applies to: 26-26, 35-35, 39-39, 47-47, 51-55, 59-60
test/concrete/parser/RaindexV6SubParser.signers.t.sol: 1
7-7: LGTM!Also applies to: 76-86
test/concrete/parser/RaindexV6SubParser.wordParsersWiring.t.sol: 1
7-14: LGTM!Also applies to: 17-19, 21-24, 27-28, 31-32, 35-41

Review info
-
Run configuration-
- Source mode: Auto
- Repository: rainlanguage/raindex.deploy
- Branch: main
- File: .coderabbit.yaml
- Commit: f971796
- Layers: Repository YAML
- Review profile: CHILL
- Plan: Advanced
- Run ID:
6b28ae7c-c463-4d4b-b1d8-473aac7975bf
Files ignored due to path filters: 6-
src/generated/RaindexV6SubParserPointers.solis excluded by!**/generated/**src/generated/candidate/GenericPoolRaindexV6ArbOrderTaker.solis excluded by!**/generated/**src/generated/candidate/GenericPoolRaindexV6FlashBorrower.solis excluded by!**/generated/**src/generated/candidate/RaindexV6.solis excluded by!**/generated/**src/generated/candidate/RaindexV6SubParser.solis excluded by!**/generated/**src/generated/candidate/RouteProcessorRaindexV6ArbOrderTaker.solis excluded by!**/generated/**
Files selected for processing: 16-
crates/test_fixtures/abis/RaindexV6.jsoncrates/test_fixtures/abis/RaindexV6SubParser.jsonmeta/RaindexV6SubParser.rain.metameta/RaindexV6SubParserAuthoringMeta.rain.metasrc/concrete/parser/RaindexV6SubParser.solsrc/concrete/raindex/RaindexV6.solsrc/lib/LibRaindex.solsrc/lib/LibRaindexSubParser.soltest/concrete/parser/RaindexV6SubParser.operandHandlersWiring.t.soltest/concrete/parser/RaindexV6SubParser.routing.t.soltest/concrete/parser/RaindexV6SubParser.routingTokenDecimalsAndMasks.t.soltest/concrete/parser/RaindexV6SubParser.signers.t.soltest/concrete/parser/RaindexV6SubParser.wordParsersWiring.t.soltest/concrete/raindex/RaindexV6.contextWordEntrypoints.t.soltest/util/fixture/LibRaindexSubParserContextFixture.soltest/util/lib/LibTestContextWords.sol
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
-
Problem
Context words compiled by the sub parser are plain
context<col row>reads, and every raindex post-task entrypoint reused the same calling-context column for unrelated data. So a word read in an entrypoint it was not written for silently returned another entrypoint's value instead of failing:deposit-*/withdraw-*/ order words all read column 1, so e.g.order-hash()in a deposit task returned the deposit token,deposit-vault-id()in an add-order task returned the owner (Post-action context: subparser words silently alias other fields or revert OOB (generalizes Protofire M02 #2619) #2647).order-counterparty()in add/remove order tasks read a row that was never filled (Audit (Protofire M02): order-counterparty() exposed in add/remove post-actions but its context row is never populated (reverts) #2619, Protofire M02).order-clearer()/depositor()/withdrawer()all aliased base(0,0)and read a value in every entrypoint.& 0xFF(signers subparser word uses the raw operand as row without & 0xFF masking (unlike signed-context) #2653).Property this PR enforces, for the raindex entrypoints: every context word reads its true value in its entrypoint, or reverts loudly (array OOB panic
0x32). Never a silent wrong value.Fix
Per-entrypoint-family context columns (
CALLING_CONTEXT_COLUMNS = 6). Each raindex entrypoint fills only its own columns; every other column is empty, so a wrong-entrypoint word panics out of bounds.[sender, raindex][hash, owner, counterparty, clearer][hash, owner]only)[token, vaultId, before, after, decimals, depositor][token, vaultId, before, after, target, decimals, withdrawer]order-clearermoves to(1,3),depositorto(5,5),withdrawerto(6,6); nothing reads base(0,0)any more.order-counterpartyin add/remove still reverts: there is no counterparty, and a zero sentinel would be a silent wrong value.CONTEXT_COLUMNS(CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN = CONTEXT_COLUMNS, start = signers + 1).signer<256>fails parse withContextGridOverflow); the redundant& 0xFFon the signed-context row is removed (operand bytes are already single bytes); column-byte extraction mask kept.mainapart from the shared signers/signed-context renumbering.Why this design
Rejected alternatives:
context<a b>defeats it).Evidence
RaindexV6.contextWordEntrypoints.t.sol: every word x {deposit4, withdraw4, addOrder4, removeOrder3, entask2, calculate-io, handle-io}: true value in its family,stdError.indexOOBErrorelsewhere; order hash pinned in calculate and handle via store writes.RaindexV6SubParser.signers.t.sol:signer<256>revertsContextGridOverflow(7, 256).Full
forge teston e464be1 (merge ofmain@ f971796): 736 passed / 3 failed (739). The 3 failures are env/network (testIsStartBlockFlare,testSuitesLiveOnEverySupportedNetwork,testSupportedNetworkChainIdsAreBound). Regeneration with rainix sol-shell @ 2aea60e5 (build-meta.sh, Build.sol until stable, forge build, script/build.sh, forge fmt) is committed.QA
RaindexV6ContextWordEntrypointsTest(testDepositContextWords,testWithdrawContextWords,testAddOrderContextWords,testRemoveOrderContextWords,testEntaskContextWords,testCalculateOrderContextWords,testHandleIOContextWords),testSubParserContextSignerUnhappyIndexOverflow. Each pins every word x entrypoint: true value in its family,stdError.indexOOBErrorelsewhere. Base cannot pass them: there deposit/withdraw/order words share calling-context column 1 (wrong-entrypoint reads return another family's value instead of reverting) and the clearer/depositor/withdrawer words do not exist.testAddOrderContextWords; CALLING_CONTEXT_COLUMNS+1 ->testRouteSignersRowFromOperand,testSubParserContextSignerUnhappyIndexOverflow; signers column-1 ->testDepositTaskSignerWordsReadRealSigners; signed-context start+1 ->testDepositTaskSignerWordsReadRealSigners. RaindexV6: deposit/withdraw column swap and depositor/withdrawer value ->testDepositContextWords/testWithdrawContextWords; add/remove post column and owner ->testAddOrderContextWords; clearer=counterparty ->testContextEmptyStack. LibRaindexSubParser: clearer row, depositor/withdrawer/deposit-token/withdraw-decimals columns ->testRouteOrderClearer,testRouteDepositor,testRouteWithdrawer,testDepositContextWords,testWithdrawContextWords; restored signed-context row& 0xFF->testSignedContextWideRowReverts; meta at wrong column -> matrix tests. RaindexV6SubParser: parser/handler table column swaps and base/depositor parser swaps -> matrix tests,testWordParsersPairwiseDistinct. Script and per-mutant logs: /home/gildlab/artifacts/raindex-2921-arb-revert-2026-10-26-mutation/.msg.sendervia prank, token, vault id, amounts, order owner/counterparty), independent of the sub parser and ofLibRaindex.signer<256>revertsContextGridOverflow); the redundant& 0xFFon the signed-context row is removed so both reject wide rows the same way.Migration
context<5 i>/context<6+i j>->context<7 i>/context<8+i j>.context<1 n>->context<5 n>/context<6 n>.ContextV2event order column gains a 4th row (clearer).Supersedes #2779 and #2778.
Closes #2619
Closes #2647
Closes #2653
🤖 Generated with Claude Code