fix: decode sign-extended narrow signed integers - #68
Conversation
| @@ -0,0 +1,28 @@ | |||
| import { describe, expect, it } from "vitest"; | |||
There was a problem hiding this comment.
Test files in this repo are named after the module they test (formatters.spec.ts, fields.spec.ts). bytesToSignedBigInt lives in src/utils.ts, so please move these tests to a new test/utils.spec.ts. Please also add that file to the test file list in AGENTS.md.
| import { bytesToSignedBigInt } from "../src/utils.js"; | ||
|
|
||
| function abiWord(value: bigint): Uint8Array { | ||
| const hex = BigInt.asUintN(256, value).toString(16).padStart(64, "0"); | ||
| return Uint8Array.from(Buffer.from(hex, "hex")); | ||
| } |
There was a problem hiding this comment.
src/utils.ts already has bigIntToBytes. It encodes a bigint as a 32-byte two's-complement word, which is what abiWord does here. Please use it and remove this helper. This also removes the Node-only Buffer from the test. The calls on lines 14 and 20 then become bigIntToBytes(value).
| import { bytesToSignedBigInt } from "../src/utils.js"; | |
| function abiWord(value: bigint): Uint8Array { | |
| const hex = BigInt.asUintN(256, value).toString(16).padStart(64, "0"); | |
| return Uint8Array.from(Buffer.from(hex, "hex")); | |
| } | |
| import { bigIntToBytes, bytesToSignedBigInt } from "../src/utils.js"; |
| }); | ||
| } | ||
| } | ||
| it("decodes actual negative Uniswap ticks", () => { |
There was a problem hiding this comment.
Non-blocking: these tests cover the helper only. The bug shows in decodeWord in src/calldata.ts. A test through format() with an int24 field would also cover that path. The negative Uniswap ticks from the PR description are a good case for a new folder under test/registry-cases.
…case - Rename test/signed-integers.spec.ts to test/utils.spec.ts and use bigIntToBytes - Add Ekubo Positions registry case with sign-extended int32 ticks - Document test layout rules in AGENTS.md
- Add pad32, padAddr, padInt and padRight32 to test/utils.ts - Replace the local copies in five test files - padInt encodes negative values as two's complement
# Conflicts: # test/utils.ts
ABI calldata containing a negative narrow signed integer currently renders an incorrect positive value. For example, an
int24Uniswap tick of-198310, sign-extended to a 32-byte ABI word, is decoded by subtracting2^24from the entire 256-bit unsigned word.Use
BigInt.asIntNto normalize the ABI word to the declared bit width and interpret its sign. Positive integers, 256-bit integers and natural-width byte inputs retain their existing meaning.Validation: 327 upstream tests pass, including 27 new regression cases spanning int8/int24/int64/int128/int256 boundaries, realistic negative Uniswap ticks and natural-width/empty inputs. An independent registry test runner with a real account descriptor improves from 18/21 cases to 21/21 with this patch; only the three signed-tick cases change.
Build, TypeScript checks, formatting and ESLint checks pass.