Skip to content

fix(bridge): correct NEAR Intents fee calculation for BTC destinations - #929

Merged
limitofzero merged 1 commit into
cowprotocol:mainfrom
gitshreevatsa:fix/near-intents-fee-calc
Jul 29, 2026
Merged

fix(bridge): correct NEAR Intents fee calculation for BTC destinations#929
limitofzero merged 1 commit into
cowprotocol:mainfrom
gitshreevatsa:fix/near-intents-fee-calc

Conversation

@gitshreevatsa

@gitshreevatsa gitshreevatsa commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What and why

NearIntentsBridgeProvider.getQuote() computed the bridge fee from the ratio of amountInUsd / amountOutUsd, and swapped which currency each fee variable was denominated in (the "buy currency" fee was computed from
amountIn, and vice versa).

This is invisible on same-magnitude routes (e.g. USDC -> USDT), but breaks visibly on BTC destinations: satoshis and USDC base units differ by orders of magnitude, so the mislabeled value produces a nonsensical fee.

Example from a production BTC bridge quote (deposit address 0x712bf81469904cee52f5ba897fd51a338f6b73e4,
https://explorer.near-intents.org/transactions/0x712bf81469904cee52f5ba897fd51a338f6b73e4):
the real worst-case gap is amountOut (7047) - minAmountOut (7011) = 36 sats, but the current code returns a fee of 1,263,735 sats, larger than the entire trade.

The fix

Derive slippage/fee from amountOut vs minAmountOut (both already in the same native units, no USD conversion involved) instead of the USD ratio, and assign each fee variable to the correct currency.

How to test

New test added: should compute a sane BTC-denominated fee for a real production BTC bridge quote, using the real numbers above. It asserts the BTC-denominated fee can never exceed the BTC amount being bridged, and pins
the exact before/after values (1263735n on main, 36n with this fix) so a future regression fails immediately.

pnpm --filter @cowprotocol/sdk-bridging test -- NearIntentsBridgeProvider


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Bug Fixes**
  * Improved bridge fee and slippage calculations for Arbitrum-to-Bitcoin transfers.
  * Fee and slippage values are now derived from the actual quote’s output and minimum output amounts, resulting in more accurate displayed results.
  * Ensured computed bridging fees don’t exceed the total bridged amount, with corrected BTC-denominated fee/slippage outputs.
* **Tests**
  * Added regression coverage for production-like BTC bridge quotes and expanded fee-related assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Near Intents quote fee and slippage calculations now use quote amount fields instead of USD payout ratios. Regression tests validate BTC-denominated fee bounds and corrected fee and slippage outputs.

Changes

Near Intents fee correction

Layer / File(s) Summary
Quote fee and slippage calculation
packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.ts, packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.test.ts
Slippage and fee components are recalculated from NEAR Intents quote amounts, with coverage for corrected currency scaling and BTC fee bounds, including bridgeFee of 36n and slippageBps of 51.

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

Possibly related PRs

  • cowprotocol/cow-sdk#926: Updates the same provider’s slippage and fee calculations and related expected outputs.

Suggested reviewers: alfetopito, shoom3301

🚥 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 change: correcting NEAR Intents fee calculation for BTC destination quotes.
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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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.

@gitshreevatsa

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@shoom3301

Copy link
Copy Markdown
Contributor

@gitshreevatsa could you resolve the merge conflicts please?

@gitshreevatsa
gitshreevatsa force-pushed the fix/near-intents-fee-calc branch from 5a1f6aa to 1ed60c3 Compare July 21, 2026 16:55
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
@gitshreevatsa

gitshreevatsa commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@shoom3301 Merged the conflicts!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.test.ts (1)

532-539: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using BigInt math for exact fee expectations.

Using Number() for token amounts can lead to loss of precision for values larger than Number.MAX_SAFE_INTEGER (like the 18-decimal amountOut here). While it mathematically works for the current fixtures, using exact BigInt math eliminates floating-point concerns, perfectly models on-chain math, and makes the expectations cleaner.

♻️ Proposed refactor for exact token math
-        const slippage = (Number(amountOut) - Number(minAmountOut)) / Number(amountOut)
         const bridgingFee = quote.amountsAndCosts.costs.bridgingFee
 
         // The sell-currency fee must be denominated in the sell token (USDC, 6 decimals) and thus
         // scaled by amountIn; the buy-currency fee in the buy token (ETH, 18 decimals), scaled by
         // amountOut. Before the fix these two were swapped (each reported in the wrong token).
-        expect(bridgingFee.amountInSellCurrency).toBe(BigInt(Math.trunc(Number(amountIn) * slippage)))
-        expect(bridgingFee.amountInBuyCurrency).toBe(BigInt(Math.trunc(Number(amountOut) * slippage)))
+        const expectedSellFee = (BigInt(amountIn) * (BigInt(amountOut) - BigInt(minAmountOut))) / BigInt(amountOut)
+        const expectedBuyFee = BigInt(amountOut) - BigInt(minAmountOut)
+
+        expect(bridgingFee.amountInSellCurrency).toBe(expectedSellFee)
+        expect(bridgingFee.amountInBuyCurrency).toBe(expectedBuyFee)
🤖 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
`@packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.test.ts`
around lines 532 - 539, Update the fee expectations in the test around slippage,
amountIn, and amountOut to use exact BigInt arithmetic instead of Number
conversions and Math.trunc. Preserve the existing sell-token scaling by amountIn
and buy-token scaling by amountOut while modeling the slippage calculation
without floating-point precision loss.
🤖 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.

Nitpick comments:
In
`@packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.test.ts`:
- Around line 532-539: Update the fee expectations in the test around slippage,
amountIn, and amountOut to use exact BigInt arithmetic instead of Number
conversions and Math.trunc. Preserve the existing sell-token scaling by amountIn
and buy-token scaling by amountOut while modeling the slippage calculation
without floating-point precision loss.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a7b72aa4-f1eb-409d-be6b-5e6cca0220cf

📥 Commits

Reviewing files that changed from the base of the PR and between 5a1f6aa and 1ed60c3.

📒 Files selected for processing (2)
  • packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.test.ts
  • packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bridging/src/providers/near-intents/NearIntentsBridgeProvider.ts

@limitofzero
limitofzero merged commit ef6dc40 into cowprotocol:main Jul 29, 2026
14 of 16 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants