Found by the independent review of #321 (#321 (comment)). The code is correct today; the regression guard is missing.
The gap.resolveTokenDecimals() in src/shared/approvalAmount.js handles decimals: 0 correctly, but nothing asserts it. The reviewer mutated both if (d !== null) return d; guards to a truthy if (d) — the same falsy-zero trap already filed as #318 — and all 788 tests stayed green while a 0-decimal token silently fell through to the unknown-scale rendering. A zero-decimal ERC-20 is legitimate and would render as "decimals unknown" instead of its true quantity.
The duplication.toDecimals exists byte-identically in src/shared/approvalAmount.js and src/shared/transferAmount.js. It is a pure uint8 parser carrying no refusal semantics, so sharing it does not couple the two screens' deliberately different unknown-scale behaviour, and MAX_DECIMALS already crosses that module boundary. The only thing the duplicate adds is drift risk — one copy losing the bigint branch would silently change which scales one screen accepts, with no test noticing.
Both are one small PR. The author of #306 correctly declined to touch transferAmount.js while it was another unit's freshly reviewed work; it has since landed, so the coupling concern is gone.
Definition of done
toDecimals is exported from src/shared/transferAmount.js and the copy in src/shared/approvalAmount.js is deleted.
A decimals: 0 assertion at the resolver level and at the rendered amount-line level.
Mutating either d !== null guard to a truthy if (d) fails a test. State the mutation and the observed result.
make check green.
Found by the independent review of https://git.eeqj.de/sneak/AutistMask/pulls/321 (https://git.eeqj.de/sneak/AutistMask/pulls/321#issuecomment-67521). The code is correct today; the regression guard is missing.
**The gap.** `resolveTokenDecimals()` in `src/shared/approvalAmount.js` handles `decimals: 0` correctly, but nothing asserts it. The reviewer mutated both `if (d !== null) return d;` guards to a truthy `if (d)` — the same falsy-zero trap already filed as https://git.eeqj.de/sneak/AutistMask/issues/318 — and **all 788 tests stayed green** while a 0-decimal token silently fell through to the unknown-scale rendering. A zero-decimal ERC-20 is legitimate and would render as "decimals unknown" instead of its true quantity.
**The duplication.** `toDecimals` exists byte-identically in `src/shared/approvalAmount.js` and `src/shared/transferAmount.js`. It is a pure uint8 parser carrying no refusal semantics, so sharing it does not couple the two screens' deliberately different unknown-scale behaviour, and `MAX_DECIMALS` already crosses that module boundary. The only thing the duplicate adds is drift risk — one copy losing the `bigint` branch would silently change which scales one screen accepts, with no test noticing.
Both are one small PR. The author of #306 correctly declined to touch `transferAmount.js` while it was another unit's freshly reviewed work; it has since landed, so the coupling concern is gone.
## Definition of done
- [ ] `toDecimals` is exported from `src/shared/transferAmount.js` and the copy in `src/shared/approvalAmount.js` is deleted.
- [ ] A `decimals: 0` assertion at the resolver level **and** at the rendered amount-line level.
- [ ] Mutating either `d !== null` guard to a truthy `if (d)` fails a test. State the mutation and the observed result.
- [ ] `make check` green.
Half done: toDecimals now exists once, in src/shared/transferAmount.js, since #349. What remains is the regression test that turns red when either d !== null guard becomes truthy.
model: claude-fable-5
Half done: `toDecimals` now exists once, in `src/shared/transferAmount.js`, since https://git.eeqj.de/sneak/AutistMask/issues/349. What remains is the regression test that turns red when either `d !== null` guard becomes truthy.
model: claude-fable-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found by the independent review of #321 (#321 (comment)). The code is correct today; the regression guard is missing.
The gap.
resolveTokenDecimals()insrc/shared/approvalAmount.jshandlesdecimals: 0correctly, but nothing asserts it. The reviewer mutated bothif (d !== null) return d;guards to a truthyif (d)— the same falsy-zero trap already filed as #318 — and all 788 tests stayed green while a 0-decimal token silently fell through to the unknown-scale rendering. A zero-decimal ERC-20 is legitimate and would render as "decimals unknown" instead of its true quantity.The duplication.
toDecimalsexists byte-identically insrc/shared/approvalAmount.jsandsrc/shared/transferAmount.js. It is a pure uint8 parser carrying no refusal semantics, so sharing it does not couple the two screens' deliberately different unknown-scale behaviour, andMAX_DECIMALSalready crosses that module boundary. The only thing the duplicate adds is drift risk — one copy losing thebigintbranch would silently change which scales one screen accepts, with no test noticing.Both are one small PR. The author of #306 correctly declined to touch
transferAmount.jswhile it was another unit's freshly reviewed work; it has since landed, so the coupling concern is gone.Definition of done
toDecimalsis exported fromsrc/shared/transferAmount.jsand the copy insrc/shared/approvalAmount.jsis deleted.decimals: 0assertion at the resolver level and at the rendered amount-line level.d !== nullguard to a truthyif (d)fails a test. State the mutation and the observed result.make checkgreen.Half done:
toDecimalsnow exists once, insrc/shared/transferAmount.js, since #349. What remains is the regression test that turns red when eitherd !== nullguard becomes truthy.model: claude-fable-5