Feat/limitAmount scaling - #255
Conversation
size-limit report 📦
|
There was a problem hiding this comment.
Pull request overview
Centralizes limitAmount scaling for cross-chain Delta SELL limit orders by converting integrator-provided destination-token wei into on-chain “bridge units” inside the SDK’s buildDeltaOrder request payload, reducing the chance of clients forgetting bridge scaling.
Changes:
- Added
toOrderLimitAmounthelper that applies bridgescalingFactor(ceil-rounded when dividing) for SELL bridge routes; otherwise returnslimitAmountunchanged. - Updated
buildDeltaOrderto sendlimitAmount: toOrderLimitAmount(params)instead of passing through the caller string. - Added comprehensive Jest coverage for scaling edge cases and for the build request payload; clarified
buildExternalDeltaOrderdocs.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/limitAmount.test.ts | Adds unit tests for scaling/rounding behavior and verifies buildDeltaOrder sends the scaled/unscaled payload as intended. |
| src/methods/delta/helpers/limitAmount.ts | Introduces toOrderLimitAmount and bridge scaling logic using BigInt with ceil rounding for SELL bridge routes. |
| src/methods/delta/buildExternalDeltaOrder.ts | Doc clarification that external orders’ limitAmount is in on-chain units (no bridge scaling). |
| src/methods/delta/buildDeltaOrder.ts | Applies centralized limit amount conversion before sending build request to the API; expands JSDoc around units/scaling behavior. |
Suppressed comments (1)
src/methods/delta/helpers/limitAmount.ts:15
- The top-level description says it converts a limit amount expressed in destination-token units, but the function only converts for SELL bridge routes and returns BUY amounts unchanged (BUY
limitAmountis in src-token units). Reword the description to avoid implying BUY inputs are destination-denominated.
/**
* @description Converts a limit amount expressed in destination-token units into the
* units the on-chain Order carries.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| type ToOrderLimitAmountParams = { | ||
| /** @description The limit amount in destination-token wei. */ | ||
| limitAmount?: string; |
There was a problem hiding this comment.
This isn't true if I'm not mistaken
There was a problem hiding this comment.
Checked in API: on BUY limitAmount becomes srcAmount, so it is origin src-token units.
Changed the docs to match
andriy-shymkiv
left a comment
There was a problem hiding this comment.
Great improvement
Wanna bump viem version together with this (breaking) change?
| slippage?: number; | ||
| /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ | ||
| /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount. | ||
| * In on-chain Order units. External orders carry no bridge, so no scaling applies. */ |
There was a problem hiding this comment.
I didn't get what "In on-chain Order units" means until I checked Widget's code
Maybe:
In dest token units?
In output token units?
There was a problem hiding this comment.
API actually has a strict no such field allowed for limitAmount in TWAP and External Orders.
So I removed the prop for them outright
I updated local dev copy of |
Centralizes
limitAmounthandling for Delta orders: the SDK now applies bridge scaling itself, and the parameter is gone from the two builders whose endpoint never accepted it.1.
buildDeltaOrderscaleslimitAmounton cross-chain SELL orderslimitAmountis passed in destination-token wei — the same units asroute.destination.output.amount. On a bridge route the on-chain Order carriesdestAmountin bridge units, so the SDK now appliesroute.bridge.contractParams.scalingFactorfor you, rounding up so the minimum you receive never lands below what you asked for.Previously every integrator had to do this themselves, and missing it set a limit wrong by
10 ** scalingFactor.Migration: if you were applying the bridge scaling before calling
buildDeltaOrder, stop — it would now be applied twice.Unaffected: same-chain routes, BUY orders, and
scalingFactor === 0.2.
limitAmountremoved frombuildExternalDeltaOrderandbuildTWAPDeltaOrderThe parameter could never work.
POST /v2/delta/orders/buildparses its body with a discriminated union whose members are all.strict(), andlimitAmountis declared only on theOrdervariant — sending it from an External or TWAP builder was rejected as an unrecognized key. It stayed latent becauseundefinedis dropped from the JSON body, so nobody had passed it.Dropped from
BuildExternalDeltaOrderParams,BuildTWAPSellDeltaOrderParamsandBuildTWAPBuyDeltaOrderParams, which turns a runtime 400 into a compile-time error.Migration: remove the argument. TWAP amounts are set by
totalSrcAmount(sell) ortotalDestAmount+maxSrcAmount(buy).New
DeltaTransaction.originReceivedAmount/.destinationReceivedAmountThe server now reports both legs of a fill explicitly:
originReceivedAmount—order.destTokendelivered on the origin chain byoriginTx; same leg, chain and decimals asspentAmount.destinationReceivedAmount—bridge.outputTokendelivered onbridge.destinationChainId, already scaled bybridge.scalingFactor.nullon same-chain fills and while a bridge leg is in flight.The existing
receivedAmountreports whichever leg matches the order and is not gated on the bridge having filled, so it can carry a destination amount recorded before delivery. Prefer the explicit pair. All four fields are now documented on the type.getAuctionAmountsreports the executeddestAmounton the right legOrderHelpers.getters.getTransactionAmountstakes an optional{ crosschain }and reads the leg theoutputtoken actually sits on —destinationReceivedAmountfor bridge orders,originReceivedAmountotherwise — mirroring how the server derivesoutput.executedAmount. Omitting the option keeps the previousreceivedAmountsum, so the exported helper stays source-compatible.Fixes
limitAmountdocs are now side-specific. They previously said "destination-token wei" unconditionally, but on BUY the server assignslimitAmounttosrcAmountand validates it againstroute.origin.input.amount— origin src-token units, never bridge-scaled.Maintenance
dts-cli@2.0.5(already the latest) pinsts-jest@29.2.5(>=4.3 <6) androllup-plugin-dts@5.3.1(^4.1 || ^5.0). TS 6 was tried and does typecheck cleanly, but ts-jest fails to resolve jest's globals under it and no tests run.pnpm peers checkis now clean.viemruntime range stays^2.21.0and theaxiospeer range stays>=0.25.0 <2.0.0, so nothing narrows for consumers.tsconfig.jsongains"lib": ["es2022", "dom", "dom.iterable"]— viem'soxdependency ships.tssources needing es2022 features, whichskipLibCheckdoes not cover.targetstayses2020, so emit is unchanged.Tests
tests/limitAmount.test.tscovers the scaling and rounding edge cases, the build request payload, and guards that neither sibling builder putslimitAmountin the body.tests/auctionAmounts.test.tspins which leg each amount is read from. 182 tests pass;tsc --noEmitandpnpm buildare clean.Note
Medium Risk
Changes how cross-chain SELL limit amounts are encoded and removes builder params; wrong migration (double scaling) or misunderstood leg amounts could mis-set order bounds for integrators.
Overview
v11.0.0 ships Delta order-building and amount-reporting fixes that integrators on bridge routes should read before upgrading.
buildDeltaOrdernow convertslimitAmountfor cross-chain SELL orders viatoOrderLimitAmount: callers keep passing destination-token wei (likeroute.destination.output.amount), and the SDK scales into on-chain bridge units usingroute.bridge.contractParams.scalingFactor, rounding up so the minimum receive never falls below the requested amount. Integrators who already applied this scaling must stop — otherwise limits are applied twice. Same-chain SELL, BUY (originsrcAmount, never scaled), andscalingFactor === 0are unchanged.Breaking API cleanup:
limitAmountis removed frombuildExternalDeltaOrderandbuildTWAPDeltaOrderbecause the build endpoint’s strict schema only allows it on the plainOrdervariant; the key is no longer sent on those requests.Fill reporting:
DeltaTransactionaddsoriginReceivedAmountanddestinationReceivedAmount(required on the type for constructors/mocks).getTransactionAmounts/getAuctionAmountscan sum executeddestAmountfrom the leg where the auctionoutputtoken lives whencrosschainis set, instead of relying on legacyreceivedAmount.Dev-only: TypeScript 5.9.3, TypeDoc 0.28, lockfile updates, and
tsconfiglibes2022 for viem/ox sources.Reviewed by Cursor Bugbot for commit 579e51a. Bugbot is set up for automated code reviews on this repo. Configure here.
closes FRNT-1398, FRNT-1399