Skip to content

fix(abi): correct encodeMatcherInitPassive wire layout + computeVammQuote skew/rounding - #336

Open
Morenikeoa wants to merge 2 commits into
dcccrypto:mainfrom
Morenikeoa:fix/matcher-init-passive-wire-layout
Open

fix(abi): correct encodeMatcherInitPassive wire layout + computeVammQuote skew/rounding#336
Morenikeoa wants to merge 2 commits into
dcccrypto:mainfrom
Morenikeoa:fix/matcher-init-passive-wire-layout

Conversation

@Morenikeoa

@Morenikeoa Morenikeoa commented Jun 26, 2026

Copy link
Copy Markdown

Problem

1. encodeMatcherInitPassive's documented wire layout didn't match the actual on-chain program. I verified InitParams::parse in percolator-match/src/vamm.rs byte-for-byte. From offset 1 onward, the function's own layout comment was wrong:

  • [10..14] was written as a literal 100, documented as "default max_inventory_abs slot" — the program actually reads this range as max_total_bps, silently capping the LP at a 1% combined spread/fee ceiling.
  • [50..66] was left zero, documented as "reserved" — the program actually reads this range as max_inventory_abs, which the matcher treats 0 as meaning unlimited.

Net effect: anyone using this encoder as documented would deploy an LP with unlimited inventory risk and almost no ability to charge spread to compensate — a dangerous silent misconfiguration. The only existing test re-asserted the function's own (wrong) documented layout, so it never caught the mismatch.

2. computeVammQuote (the "Smart Price Router" quote estimator) systematically underestimates the real on-chain execution price. Two independent gaps, both biased the same direction: VammMatcherParams had no field for LP inventory/skew at all, so the on-chain skew-aware spread widening (compute_skew_extra_bps) was never modeled; and the buy-side division used floor instead of the on-chain ceiling division ("LP never under-charges").

Fix

  • Corrected encodeMatcherInitPassive's field-to-offset mapping and expanded MatcherInitPassiveArgs to actually accept the fields the wire format requires (tradingFeeBps, baseSpreadBps, maxTotalBps, maxInventoryAbs were previously unsettable).
  • Added inventoryBase/skewSpreadMultBps to VammMatcherParams and ported compute_skew_extra_bps's exact logic into computeVammQuote; switched the buy-side division to ceiling.
  • Closed the parity-test gap that let bug PERC-150: Add detailed README + Apache 2.0 license #1 ship undetected: sdk_parity_fixtures.rs already emits the correct init_field_offsets into specs/matcher-parity.json, but parity-fixtures.test.ts never read them. Added a test that encodes sentinel values through encodeMatcherInitPassive and verifies each lands at the exact offset the Rust fixture reports, so future layout drift in either direction gets caught automatically.
  • Rebuilt dist/ (this repo ships pre-built artifacts for git-dependency consumers).

No internal consumer (percolator-keeper, percolator-api) currently calls either function, but both are publicly exported with worked examples.

Note on .github/workflows/parity-gate.yml

This PR's diff includes an unrelated 15-line change to this file — my branch is based on current upstream main, but pushing that version to my fork was rejected ("refusing to allow an OAuth App to create or update workflow ... without workflow scope"), so I reverted just that file to my fork's older version to unblock the push. It's unrelated to this fix; feel free to disregard/exclude that hunk when merging.

Proof of Fix

  • New test cross-validates every encodeMatcherInitPassive field against specs/matcher-parity.json's Rust-sourced offsets (would have caught the original bug).
  • New test covers computeVammQuote's skew widening (only applies on the inventory-worsening side, capped at 5000bps) and buy-side ceiling rounding.
  • Full suite passes: npm test → 852 passed, 31 skipped (pre-existing, RPC-dependent). npm run lint clean.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved quote calculations to better match on-chain pricing, including skew-aware spread handling and safer buy-side rounding.
    • Fixed passive matcher initialization encoding so all fields are placed in the expected layout and optional values are included correctly.
  • Tests

    • Added regression coverage for quote behavior, payload size variants, and byte-offset parity checks.

Morenikeoa and others added 2 commits June 26, 2026 08:01
…uote skew/rounding

encodeMatcherInitPassive's documented byte layout did not match
InitParams::parse in percolator-match/src/vamm.rs from offset 1 onward.
Concretely: byte[10..14] was written as a literal 100 believing it was
"a default max_inventory_abs slot", but the program reads that range as
max_total_bps — silently capping the LP at a 1% combined spread/fee
ceiling. byte[50..66] was left zero believing it was "reserved", but
the program reads that range as max_inventory_abs, which the matcher
treats 0 as meaning "unlimited" — so every LP set up via this encoder
got unlimited inventory risk with almost no ability to charge spread
to compensate. The only existing test only re-asserted the function's
own (wrong) documented layout, so it never caught the mismatch.

Fixes the field-to-offset mapping and expands MatcherInitPassiveArgs to
actually accept the fields the wire format requires (trading_fee_bps,
base_spread_bps, max_total_bps, max_inventory_abs were previously
unsettable). Rewrites the test to cross-validate every field against
the real offsets, and adds the 78-byte extended-payload path.

Also fixes computeVammQuote, which estimates a vAMM LP's execution
price for client-side LP selection ("Smart Price Router"): it omitted
the on-chain skew-aware inventory widening entirely (VammMatcherParams
had no field for it) and floor-divided the buy-side price instead of
ceiling-dividing like compute_vamm_execution does. Both gaps made every
buy-side quote estimate against a skewed LP systematically lower than
the real on-chain price. Adds inventoryBase/skewSpreadMultBps to
VammMatcherParams, ports compute_skew_extra_bps's exact logic, and
switches the buy-side division to ceiling. No internal consumer
(percolator-keeper, percolator-api) currently calls this function, but
it's publicly exported with a worked example.

Separately: closes the parity-test gap that let the encoder bug ship
undetected. sdk_parity_fixtures.rs already emits the correct
init_field_offsets into specs/matcher-parity.json, but
parity-fixtures.test.ts never read them — it only checked top-level
sizes/magic/self-checks. Adds a test that encodes sentinel values and
verifies each one lands at the exact offset the Rust fixture reports,
so a future layout drift in either direction would be caught
automatically instead of requiring a manual byte-by-byte re-audit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unrelated to this fix — avoids pushing a workflow-file change my
token lacks the `workflow` OAuth scope for. The matcher.dcccrypto's
upstream version of this file will reconcile normally when this
branch is rebased/merged there directly rather than via the fork.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The workflow now passes PERCOLATOR_READ_TOKEN to Rust repository checkouts and documents the secret setup. The ABI helpers update passive matcher quote math and matcher init payload encoding, with tests covering the new quote and byte layouts.

Changes

Workflow token wiring

Layer / File(s) Summary
Checkout token wiring
.github/workflows/parity-gate.yml
Comments document PERCOLATOR_READ_TOKEN setup for the percolator-sdk checkout, and the Rust repo checkout steps now pass secrets.PERCOLATOR_READ_TOKEN.

Matcher ABI and parity checks

Layer / File(s) Summary
Quote parameters and skew pricing
src/abi/instructions.ts, test/abi.test.ts
VammMatcherParams adds inventory and skew fields, computeVammQuote applies skew-aware spread and ceiling-style buy rounding, and tests cover the updated quote math.
Passive init payload encoding
src/abi/instructions.ts, test/abi.test.ts, test/parity-fixtures.test.ts
MatcherInitPassiveArgs expands to core and optional fields, encodeMatcherInitPassive emits 66-byte or 78-byte payloads, and tests verify field bytes and fixture offsets.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • dcccrypto/percolator-match issue 26 — The passive matcher init and encodeMatcherInitPassive changes match the issue’s passive initialization and ABI encoding updates.

Poem

🐰 I hopped through bytes and token strings,
and twitched my nose at quote-y things.
The matcher fit, the offsets shone,
the skew and spread were right at home.
A carrot cheers this tidy PR!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main ABI fix: correcting encodeMatcherInitPassive layout and computeVammQuote skew/rounding behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/parity-gate.yml:
- Line 48: The new actions/checkout usages in the parity-gate workflow are still
pinned to the mutable v4 tag, which violates the action pinning policy. Update
each checkout reference in the workflow to a full commit SHA instead of `@v4`,
making sure all four occurrences are changed consistently so the workflow
remains policy-compliant.
- Around line 47-73: The four actions/checkout steps for percolator-prog,
percolator-stake, percolator-nft, and percolator-match are persisting the token
in git config unnecessarily; update each checkout block to disable credential
persistence. Add the hardening option to every tokenized checkout so the
PERCOLATOR_READ_TOKEN is not retained for later steps, and keep the change
localized to the checkout configuration only.
- Around line 37-44: The Rust checkout steps are unconditionally wiring in the
optional read token, which breaks the public/no-secret path when the secret is
unset. Update the four checkout uses in the parity-gate workflow to only supply
the token when PERCOLATOR_READ_TOKEN exists, and otherwise let actions/checkout
fall back to its default GITHUB_TOKEN behavior. Keep the change scoped to the
checkout steps so the existing public/forked PR flow remains intact.

In `@test/parity-fixtures.test.ts`:
- Around line 272-282: The fixture parity check is missing coverage for the
`impact_k_bps` init field, so an offset regression there could slip through.
Update the parity test in `test/parity-fixtures.test.ts` to also read and assert
`offsets.impact_k_bps` alongside the other init-field offset checks, using the
same `readU32` helper pattern in the existing test block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5bef5717-b847-4907-a675-a30bd122d1f0

📥 Commits

Reviewing files that changed from the base of the PR and between 673bc47 and 47440cd.

⛔ Files ignored due to path filters (3)
  • dist/abi/instructions.d.ts is excluded by !**/dist/**
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
📒 Files selected for processing (4)
  • .github/workflows/parity-gate.yml
  • src/abi/instructions.ts
  • test/abi.test.ts
  • test/parity-fixtures.test.ts

Comment on lines +37 to +44
# If the repo is private, uncomment the token line and add
# PERCOLATOR_READ_TOKEN as a repository secret on percolator-sdk:
# Settings → Secrets and variables → Actions → New repository secret
# Name: PERCOLATOR_READ_TOKEN
# Value: a GitHub PAT (classic or fine-grained) with Contents: read
# on percolator-prog, percolator-stake, percolator-nft, percolator-match.
# If all five repos are public, this token line is not needed.
# token: ${{ secrets.PERCOLATOR_READ_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major

🧩 Analysis chain

🌐 Web query:

actions/checkout empty token string behavior public repository

💡 Result:

When using the actions/checkout action, explicitly setting the token input to an empty string (token: '') generally causes the checkout process to fail with authentication-related errors [1]. Even for public repositories, the action expects a valid token to perform authenticated Git operations [1]. By default, the action uses the ${{ github.token }} (also known as the GITHUB_TOKEN) provided by the GitHub Actions environment, which is sufficient for checking out public repositories without needing an additional personal access token (PAT) [1][2][3]. If you pass an empty string to the token input, you effectively override this default behavior [2][4]. This often results in Git errors, such as "could not read Username," because the action lacks the necessary credentials to interact with GitHub, and non-authenticated clones may be restricted or subject to stricter rate limiting [1]. In summary: 1. Do not set the token to an empty string if you want the action to succeed using its default behavior [1]. 2. For public repositories, omitting the token input entirely is the correct practice, as it allows the action to fall back to the default ${{ github.token }} [1][2]. 3. The token is also used to configure the local Git environment (persisting credentials), which enables subsequent Git commands in your workflow to run authenticated [2][5][4]. Passing an empty string prevents this configuration from occurring [4].

Citations:


🌐 Web query:

github actions unset secret evaluates to empty string

💡 Result:

In GitHub Actions, if a secret is unset, not found, or otherwise unavailable to a workflow, the expression referencing that secret evaluates to an empty string ("") [1][2]. This behavior is important for several reasons: 1. Silent Failures: Because an unset secret evaluates to an empty string rather than causing a workflow error, typos in secret names or scoping issues can lead to workflows that run with empty values instead of failing as expected [3]. 2. Conditional Logic: You cannot use secrets directly within if: conditional expressions because they are masked. If you need to check if a secret is set, you should map it to an environment variable first, then check the environment variable in your condition [2][4][5]. Example: env: MY_SECRET_VAL: ${{ secrets.MY_SECRET }} if: ${{ env.MY_SECRET_VAL!= '' }} 3. Fallback Patterns: When using fallback logic (e.g., trying to use one secret or another), you must explicitly check for the empty string. Simple boolean-style fallbacks (like variable || default) may not behave as expected because the unset secret is a string, not a falsy value [6]. Correct fallback example: ${{ secrets.OPTIONAL_TOKEN!= '' && secrets.OPTIONAL_TOKEN || secrets.DEFAULT_TOKEN }} [6] Common reasons a secret may resolve to an empty string unexpectedly include: - Incorrect scope: The secret is defined in an environment that is not explicitly linked to the job [7][5]. - Fork limitations: Workflows triggered by pull requests from forked repositories do not have access to secrets (except for GITHUB_TOKEN) for security reasons [8][9]. - Reusable workflows: When using reusable workflows, secrets must be explicitly passed or inherited using secrets: inherit [8][10].

Citations:


Preserve the no-secret public checkout path.

The comments state the token is unnecessary for public repositories, but the current implementation unconditionally passes secrets.PERCOLATOR_READ_TOKEN. Unset secrets evaluate to an empty string, and actions/checkout fails if the token input is explicitly provided as an empty string, overriding the default GITHUB_TOKEN behavior required for public/forked PR checkouts.

Apply the suggested fallback to all four Rust checkout steps (lines 52, 59, 66, 73) to ensure GITHUB_TOKEN is used when the optional secret is missing:

Proposed fallback
-          token: ${{ secrets.PERCOLATOR_READ_TOKEN }}
+          token: ${{ secrets.PERCOLATOR_READ_TOKEN || github.token }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/parity-gate.yml around lines 37 - 44, The Rust checkout
steps are unconditionally wiring in the optional read token, which breaks the
public/no-secret path when the secret is unset. Update the four checkout uses in
the parity-gate workflow to only supply the token when PERCOLATOR_READ_TOKEN
exists, and otherwise let actions/checkout fall back to its default GITHUB_TOKEN
behavior. Keep the change scoped to the checkout steps so the existing
public/forked PR flow remains intact.

Comment on lines 47 to +73
- name: Checkout percolator-prog
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/percolator-prog
path: percolator-prog
token: ${{ secrets.PERCOLATOR_READ_TOKEN }}

- name: Checkout percolator-stake
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/percolator-stake
path: percolator-stake
token: ${{ secrets.PERCOLATOR_READ_TOKEN }}

- name: Checkout percolator-nft
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/percolator-nft
path: percolator-nft
token: ${{ secrets.PERCOLATOR_READ_TOKEN }}

- name: Checkout percolator-match
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/percolator-match
path: percolator-match
token: ${{ secrets.PERCOLATOR_READ_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/parity-gate.yml | sed -n '74,200p'

Repository: dcccrypto/percolator-sdk

Length of output: 1840


Disable persisted credentials after tokenized checkouts.

Adding persist-credentials: false to the four actions/checkout steps is a valid security hardening measure. No subsequent steps in this workflow (Install Rust stable, Cache Cargo, Install pnpm, Setup Node 20, Install SDK dependencies, Run parity check) perform git operations that would require authenticated credentials. Disabling persistence minimizes the attack surface by preventing the PERCOLATOR_READ_TOKEN from lingering in the git configuration for unused steps.

Proposed hardening
-          token: ${{ secrets.PERCOLATOR_READ_TOKEN }}
+          token: ${{ secrets.PERCOLATOR_READ_TOKEN }}
+          persist-credentials: false

Apply this change to the checkout steps for percolator-prog, percolator-stake, percolator-nft, and percolator-match.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 47-52: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 54-59: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 61-66: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 48-48: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 55-55: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 62-62: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 69-69: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/parity-gate.yml around lines 47 - 73, The four
actions/checkout steps for percolator-prog, percolator-stake, percolator-nft,
and percolator-match are persisting the token in git config unnecessarily;
update each checkout block to disable credential persistence. Add the hardening
option to every tokenized checkout so the PERCOLATOR_READ_TOKEN is not retained
for later steps, and keep the change localized to the checkout configuration
only.

Source: Linters/SAST tools

# repository secrets are not provided to pull_request runs from forks.
# If they become private, add PERCOLATOR_READ_TOKEN here with Contents: read.
- name: Checkout percolator-prog
uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Pin the new checkout actions to full SHAs.

The added actions/checkout@v4 references violate the configured blanket policy for pinned actions. Pin these four references to full commit SHAs.

#!/bin/bash
# Verify no newly added checkout references remain pinned only to a mutable major tag.
rg -n 'uses:\s*actions/checkout@v[0-9]+\b' .github/workflows/parity-gate.yml

Also applies to: 55-55, 62-62, 69-69

🧰 Tools
🪛 zizmor (1.26.1)

[error] 48-48: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/parity-gate.yml at line 48, The new actions/checkout
usages in the parity-gate workflow are still pinned to the mutable v4 tag, which
violates the action pinning policy. Update each checkout reference in the
workflow to a full commit SHA instead of `@v4`, making sure all four occurrences
are changed consistently so the workflow remains policy-compliant.

Comment on lines +272 to +282
expect(data[offsets.tag]).toBe(2);
expect(data[offsets.kind]).toBe(0);
expect(readU32(offsets.trading_fee_bps)).toBe(11);
expect(readU32(offsets.base_spread_bps)).toBe(22);
expect(readU32(offsets.max_total_bps)).toBe(9000);
expect(readU128(offsets.liquidity_notional_e6)).toBe(0n);
expect(readU128(offsets.max_fill_abs)).toBe(0x1111_2222_3333_4444n);
expect(readU128(offsets.max_inventory_abs)).toBe(0x5555_6666_7777_8888n);
expect(readU16(offsets.fee_to_insurance_bps)).toBe(333);
expect(readU16(offsets.skew_spread_mult_bps)).toBe(444);
expect(readU64(offsets.lp_account_id)).toBe(0x9999_AAAA_BBBB_CCCCn);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert impact_k_bps from the fixture too.

This test says it verifies every init field offset, but offsets.impact_k_bps is never read. Since that slot is expected to be zero and sits next to other zero-filled fields, an offset regression there can still pass unnoticed.

Suggested assertion
       expect(readU32(offsets.trading_fee_bps)).toBe(11);
       expect(readU32(offsets.base_spread_bps)).toBe(22);
       expect(readU32(offsets.max_total_bps)).toBe(9000);
+      expect(readU32(offsets.impact_k_bps)).toBe(0);
       expect(readU128(offsets.liquidity_notional_e6)).toBe(0n);
       expect(readU128(offsets.max_fill_abs)).toBe(0x1111_2222_3333_4444n);
       expect(readU128(offsets.max_inventory_abs)).toBe(0x5555_6666_7777_8888n);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
expect(data[offsets.tag]).toBe(2);
expect(data[offsets.kind]).toBe(0);
expect(readU32(offsets.trading_fee_bps)).toBe(11);
expect(readU32(offsets.base_spread_bps)).toBe(22);
expect(readU32(offsets.max_total_bps)).toBe(9000);
expect(readU128(offsets.liquidity_notional_e6)).toBe(0n);
expect(readU128(offsets.max_fill_abs)).toBe(0x1111_2222_3333_4444n);
expect(readU128(offsets.max_inventory_abs)).toBe(0x5555_6666_7777_8888n);
expect(readU16(offsets.fee_to_insurance_bps)).toBe(333);
expect(readU16(offsets.skew_spread_mult_bps)).toBe(444);
expect(readU64(offsets.lp_account_id)).toBe(0x9999_AAAA_BBBB_CCCCn);
expect(data[offsets.tag]).toBe(2);
expect(data[offsets.kind]).toBe(0);
expect(readU32(offsets.trading_fee_bps)).toBe(11);
expect(readU32(offsets.base_spread_bps)).toBe(22);
expect(readU32(offsets.max_total_bps)).toBe(9000);
expect(readU32(offsets.impact_k_bps)).toBe(0);
expect(readU128(offsets.liquidity_notional_e6)).toBe(0n);
expect(readU128(offsets.max_fill_abs)).toBe(0x1111_2222_3333_4444n);
expect(readU128(offsets.max_inventory_abs)).toBe(0x5555_6666_7777_8888n);
expect(readU16(offsets.fee_to_insurance_bps)).toBe(333);
expect(readU16(offsets.skew_spread_mult_bps)).toBe(444);
expect(readU64(offsets.lp_account_id)).toBe(0x9999_AAAA_BBBB_CCCCn);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/parity-fixtures.test.ts` around lines 272 - 282, The fixture parity
check is missing coverage for the `impact_k_bps` init field, so an offset
regression there could slip through. Update the parity test in
`test/parity-fixtures.test.ts` to also read and assert `offsets.impact_k_bps`
alongside the other init-field offset checks, using the same `readU32` helper
pattern in the existing test block.

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