Skip to content

Bound set-price-cap maxChangeE2bps to u64 on the number path - #2494

Open
0x-SquidSol wants to merge 1 commit into
dcccrypto:playgroundfrom
0x-SquidSol:fix/set-price-cap-number-u64-bound
Open

Bound set-price-cap maxChangeE2bps to u64 on the number path#2494
0x-SquidSol wants to merge 1 commit into
dcccrypto:playgroundfrom
0x-SquidSol:fix/set-price-cap-number-u64-bound

Conversation

@0x-SquidSol

@0x-SquidSol 0x-SquidSol commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What

Reject maxChangeE2bps above u64 max on the number input path of
/api/oracle/set-price-cap (the string path already does this).

Why

The number path validated integer + non-negative but had no upper bound, so a JS
number like 1e21 (a non-negative integer that overflows u64) passed and was handed
to encodeSetOraclePriceCap. Admin-only, so the impact is a malformed request
rather than an attack — but it should return 400, consistent with the string path.

Changes

  • set-price-cap: add the same > 0xffff_ffff_ffff_ffff check on the number path.
  • regression test: 1e21 rejected; legit values (incl. MAX_SAFE_INTEGER, 0) pass;
    string-path parity documented.

Testing

  • npx tsc --noEmit — clean.
  • New test + oracle-set-price-cap — 2 files, 8 tests, all pass.

Notes

  • Frontend + devnet scope; no program/keeper/mainnet changes.

Summary by CodeRabbit

  • Bug Fixes
    • Added validation to reject numeric price-cap values exceeding the supported 64-bit unsigned integer range.
    • Invalid oversized values now return a clear HTTP 400 response instead of being processed.
    • Valid values, including zero and the maximum safe integer, continue to be accepted.

…path

The route rejects maxChangeE2bps > u64max only when it arrives as a string. On the
`number` path it checked integer + non-negative but no upper bound, so a JS number
like 1e21 (a non-negative integer that overflows u64) passed and was handed to
encodeSetOraclePriceCap. Admin-only, so the impact is a malformed request rather
than an attack — but it should 400, matching the string path.

- set-price-cap: reject maxChangeE2bps > u64max on the number path too
- add a regression test (1e21 rejected; legit values incl. MAX_SAFE_INTEGER pass)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@0x-SquidSol
0x-SquidSol requested a review from dcccrypto as a code owner August 5, 2026 19:35
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

@0x-SquidSol is attempting to deploy a commit to the Khubair Nasir's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 288d5d1f-8512-4da4-a5b4-3cbbc690482b

📥 Commits

Reviewing files that changed from the base of the PR and between f2a3bbe and 4f5d5a8.

📒 Files selected for processing (2)
  • app/__tests__/api/set-price-cap-u64-bound.test.ts
  • app/app/api/oracle/set-price-cap/route.ts

📝 Walkthrough

Walkthrough

Changes

Price cap validation

Layer / File(s) Summary
Numeric u64 validation
app/app/api/oracle/set-price-cap/route.ts, app/__tests__/api/set-price-cap-u64-bound.test.ts
Numeric maxChangeE2bps values above the u64 maximum now return HTTP 400. Tests cover overflow rejection, valid boundary values, and string-path parity.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: dcccrypto

🚥 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 and concisely describes the u64 bound added to the numeric set-price-cap path.
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 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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.

@dcccrypto dcccrypto left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Correct. Suite: 2922 passed / 0 failed.

The natural worry with a u64 bound on a JS number is float precision — but the
check runs on maxChangeE2bps after BigInt(raw), so the comparison is exact
bigint-vs-bigint, not 1e21 > 1.8446744073709552e19 in double space. The
preceding Number.isInteger guard also means BigInt(raw) can't throw. Correct
by construction, and it now matches the string path exactly.

Merge check with #2493: both touch set-price-cap/route.ts (#2493 rewrites
isAuthorized at ~:83, this adds a check at ~:120). I merged them onto
playground in sequence — clean, and the combined file carries both changes.
Whichever lands second needs no rebase.

Test doesn't bind the fix. I deleted the new block — the bug fully restored —
and set-price-cap-u64-bound.test.ts stayed 3/3 green. Binding it means
importing the route and POSTing { maxChangeE2bps: 1e21 } with the admin header,
asserting 400. Reachable now that #2493 gives you checkAdminSecret to stub.

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.

2 participants